Handling a staging environment with capistrano / rails

Just before christmas I worked with one of our customers new server cluster or cloud if you may.
This cluster has production nodes and staging nodes and this post is about how to get capistrano to play nice with both production and the staging environment.

I have googled for a solution but all solutions I found where pretty ugly so i decided to create my own. When writing this line I did a test googling just to give an example of a bad example and my first result where the buckblogs blog. A post about a plugin called multistage I do not how I could miss that ;)

But as my solution is so simple I will continue this post and show you anyway.

As usual I have written to much bullshit and I guess that you just want is some code so here you go.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
desc "Run tasks in production enviroment."
task :production do
  # Production nodes
  role :app, "192.168.1.30"
  role :app, "192.168.2.30"
  role :db,  "192.168.1.30", :primary => true
end

desc "Run tasks in staging enviroment."
task :staging do
  # Staging nodes
  role :web, "192.168.1.60"
  role :app, "192.168.2.60"
  role :db,  "192.168.1.60", :primary=>true
end

This is all there is to it. Splitting your role definitions into different tasks.
Now you may wonder how you use this when deploying or whatever you do.

Just add those tasks as params to cap.

1
2
3
4
5
cap staging deploy:check
cap staging deploy
# or
cap production deploy:check
cap production deploy

And here is a little bonus

Just to spice this up a bit I added another useful function. A little warning if you are about to deploy to your production environment. When running a big/important site you do not want to deploy into the wrong environment ;-)

This is how the final code looks.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
desc "Run tasks in production enviroment."
task :production do
  # Prompt to make really sure we want to deploy into prouction
  puts "\n\e[0;31m   ######################################################################"
  puts "   #\n   #       Are you REALLY sure you want to deploy to production?"
  puts "   #\n   #               Enter y/N + enter to continue\n   #"
  puts "   ######################################################################\e[0m\n"
  proceed = STDIN.gets[0..0] rescue nil
  exit unless proceed == 'y' || proceed == 'Y'
 
  # Production nodes
  role :app, "192.168.1.30"
  role :app, "192.168.2.30"
  role :db,  "192.168.1.30", :primary => true
end

desc "Run tasks in staging enviroment."
task :staging do
  # Staging nodes
  role :web, "192.168.1.60"
  role :app, "192.168.2.60"
  role :db,  "192.168.1.60", :primary=>true
end

When this code is used you will get something like the image below.

Warning when deploying to production

And thats all there is to it. The only thing that I think is missing is a warning/notice if you do not specify either production/staging. Like it is now you will get an error when capistrano cannot find any valid servers.

Happy deploying!

Posted in Hosting, Programming, Rails, Ruby at January 6th, 2009. Trackback URI: trackback Tags: , , , Written by: 

8 Responses to “Handling a staging environment with capistrano / rails”

I like what you’ve done and implemented it. However, I’ve run into an issue when attempting to use it. The warning prompt displays, but the multistage plugin complains about no stage being specified.

1
2
* == Currently executing `multistage:ensure'
No stage specified. Please specify one of: staging, beta, production (e.g. `cap staging deploy')

Any ideas?

JasonNo Gravatar on June 17th, 2009 at 3:57 am

Hi Jason,

Thanks for your comment. My solution to multiple deploy targets is not dependent on the multistage plugin/gem. Maybe I was to unclear in my post.

If you have any references in your deploy.rb to the multistage plugins try comment those out or uninstall the multistage plugin and I thing you will be fine.

If you do want to use the multistage plugin you can follow the instructions on Jamis blog here: http://weblog.jamisbuck.org/2007/7/23/capistrano-multistage

Thanks.

Mathias StjernströmNo Gravatar on June 17th, 2009 at 7:45 am

Ah, got it. Thanks Mathias!

JasonNo Gravatar on June 17th, 2009 at 11:25 pm

Superb!

Glad I could help.

Mathias StjernströmNo Gravatar on June 18th, 2009 at 9:46 am

To add warning/notice if you do not specify either production/staging stage, one can do following:

#####################################

set :stage, nil

task :before_deploy do
abort “ERROR: No stage specified. Please specify one of: staging, production (e.g. `cap staging deploy’)” if stage.nil?
end

desc “Run tasks in production enviroment.”
task :production do
# Production nodes
set :stage, “production”

end

desc “Run tasks in staging enviroment.”
task :staging do
set :stage, “staging”

end

#####################################

ZeeshanNo Gravatar on October 4th, 2009 at 11:42 pm

Thanks Zeeshan!

Thats a great addition!

Sheers!

Mathias StjernströmNo Gravatar on October 5th, 2009 at 6:26 pm

Thanks very much for the elegant and useful solution.

Thomas Peter BerntsenNo Gravatar on November 11th, 2009 at 3:19 pm

I don’t think that Capistrano supports role definition within tasks as of version 2.5.21. I tried to configure my tasks similarly and received errors when trying to define my roles in a similar manner.

Evan ReevesNo Gravatar on April 21st, 2011 at 2:24 am

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

pastbedti.me is using WP-Gravatar