Deploying Your Application to Multiple Environments with Capistrano
Problem
Contributed by: Ben Bleything
You want to use Capistrano to deploy your application, but you need to be able to deploy to more than one environment.
Solution
NOTE
For this recipe, we'll be assuming you have a production and a staging environment.
Capistrano is extremely flexible; it gives you a great deal of control over your deployment. To take advantage of this to accomplish your goals, set up your deployment environments inside tasks:
config/deploy.rb:
set :application, 'example'
set :repository, 'http://svn.example.com/example/trunk'
set :deploy_to, '/var/www/example'
set :user, 'vlad'
task :production do
role :web, 'www.example.com'
role :app, 'www.example.com'
role :db, 'www.example.com', :primary => true end task :staging do
role :web, 'staging.example.com'
role :app, 'staging.example.com'
role :db, 'staging.example.com', :primary => true end
Once that's in place, you can perform actions in your desired environment by chaining commands together:
$ cap staging setup
$ cap production setup deploy
Discussion
We've only really scratched the surface in this solution. By setting your environment in tasks and then chaining them together, you can create complex deployment scenarios. For instance, to initialize your environments once you've got them configured, this is perfectly valid:
$ cap staging setup deploy production setup deploy
If your environment is simpler, you may be able to simplify the deployment. For instance, if your staging environment is just another directory on the production server, you can do this:
config/deploy.rb:
set :application, 'example'
set :repository, 'http://svn.example.com/example/trunk'
set :web, 'example.com'
set :app, 'example.com'
set :db, 'example.com', :primary => true set :deploy_to, '/var/www/production'
set :user, 'vlad'
task :stage do
set :deploy_to '/var/www/staging'
deploy end
Then run your new task:
$ cap stage
To accommodate alternate environments, you may want to create new environments in your Rails application. This is as simple as cloning config/environments/production.rb:
$ cp config/environments/production.rb config/environments/staging.rb
and adding a new section to your database.yml:
config/database.yml:
common: &common
adapter: sqlite development:
database: db/dev.sqlite
<<: *common test:
database: db/test.sqlite
<<: *common production:
database: db/production.sqlite
<<: *common
staging:
database: db/staging.sqlite
<<: *common
See Also
|