Multistage deployments

technicalpickles edited this page Feb 11, 2013 · 4 revisions

Many developers prefer to have a staging server that is configured very similar to, if not completely identical to, the production server. Capistrano provides multistage deployment through the capistrano-ext gem.

Stage Configuration

Moonshine can be used with the capistrano-ext gem quite easily. Most of the deployment information for your server goes into config/moonshine.yml so we can just keep the parts that change in config/deploy.rb and the stage files under config/deploy/. For this example, we’ll assume that there are two servers- production and staging. Our deploy files would only need to contain the following.

config/deploy.rb

set :stages, %w(staging production)
require 'capistrano/ext/multistage'

config/deploy/production.rb

server "domain.com", :app, :web, :db, :primary => true

config/deploy/staging.rb

server "staging.domain.com", :app, :web, :db, :primary => true

Now you can deploy to staging with cap staging deploy or to production with cap production deploy.

Per-stage Manifest Configuration

If you have settings that need to be different between your stages, you can use the following techniques.

# only use configuration or plugins on a particular stage:
if deploy_stage == 'production'
  configure(:ssh => {:allow_users => ['rob','rails']})
  plugin :ssh
  recipe :ssh
end

# use different values depending on the stage
configure( :mysql => { 
  :extra => "bind-address = 10.0.0.#{deploy_stage == 'production' ? 10 : 20 }"
})

Within a recipe, you can use the on_stage method:

recipe custom
  # configuration for every stage

  on_stage :production do
    # configure packages, crons, etc. for production only
  end
end
recipe :custom