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.

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!
