Deploying with Capistrano

Creative Commons License The U.S. Army
At the end of April, I wrote about how automatic rsyncs were making my operations life a living hell. Enter Summer, vacation, new developer and here we are mid-September before I finally get around to permanently fixing this problem.

But, I can’t really blame all of it on life – after Matthias gave me a crash course on Capistrano basics, I was a bit daunted by recreating the application directory environment for every deploy. Symlinks, local configuration details, file permissions…oh my!

K.I.S.S.

Last weekend brought some cold rainy weather and I got around to thinking about Cap again. Could I write a simplified Cap file which would just run svn info & svn update?

Here’s my info task:

task :info, :roles => 
  defer { eval(Capistrano::CLI.ui.ask("Server roles ([:role1,:role2,...]) : ")) } do 
    run "svnversion #{deploy_dir}" do |channel, stream, data|
      data = data.chomp     # remove line separators
      result = "r" + data + " " + channel[:host]
      #check for trailing SVN status characters 'M','C',etc.
      # if (data.to_i.to_s == data)
      #  result += " => clean"
      # else
      #   result += " => contaminated"
      # end
      puts result
    end
  end

The CLI.ui.ask allows me to input the desired role group(s) at runtime. I’ve also figured out how to identify if a remote repository’s not 100% clean (which I’ve commented out for now). Here’s the sample output of a run:

danackerson ~/dev$ sudo cap info
  * executing `info'
  * executing "svnversion /data/www/svn/"
Server roles ([:role1,:role2,...]) : :all
  servers: ["db.netdoktor.de", "slave1.netdoktor.de", "slave2.netdoktor.de", "test.netdoktor.de"]
  [db.netdoktor.de] executing command
  [slave1.netdoktor.de] executing command
  [slave2.netdoktor.de] executing command
  [test.netdoktor.de] executing command
r3357 db.netdoktor.de
r3357 slave1.netdoktor.de
r3357 test.netdoktor.de
r3357 slave2.netdoktor.de
  command finished

Nice. Why sudo you may ask? Just because I’ve made deployment drop-dead easy, doesn’t mean I should be able to cold-cock my application. With great power comes great responsibility, and I reassert this by making my cap file executable only by root.

Where the Rubber Meets the Road

Ok, I’d cut my teeth and gained confidence that I could write custom cap tasks to accomplish important goals. Now time for the main event: svn update:

task :update, :roles => 
  defer { eval(Capistrano::CLI.ui.ask("Server roles ([:role1,:role2,...]) : ")) } do 
    rev = ENV['REV'];
    if rev == nil 
      rev = "HEAD"
    end 
    run "svn update -r#{rev} #{deploy_dir}"
end

The REV env variable gives me the ability to specify a specific revision (useful for a rollback as well):

danackerson ~/dev$ sudo cap update REV=3356
  * executing `update'
  * executing "svn update -r3356 /data/www/svn/"
Server roles ([:role1,:role2,...]) : :test
    servers: ["test.netdoktor.de"]
    [test.netdoktor.de] executing command
  ** [out :: test.netdoktor.de] U    /data/www/svn/do_news.gif
  ** [out :: test.netdoktor.de] U    /data/www/svn/do_arzt.gif
  ** [out :: test.netdoktor.de] U    /data/www/svn/do_forum.gif
  ** [out :: test.netdoktor.de] Updated to revision 3356.
    command finished

Leaps and Bounds

After putting the final touches on this Monday morning, I gave it a thorough workout. Not only did I notice a signficant time savings in using cap, but I suddenly had extremely fine deployment possibilities. By the time the day was through, I was running 4 different versions of our codebase among the various servers. This probably sounds horrifying, but it really allowed us to insulate the productive slaves from untested (and unnecessary) code changes. The sudo cap info script gave me a quick overview of exactly what was running where.

Ultimately, it only cost me a few hours to get this setup and I certainly wish I would have done it like this four months ago. How are you using capistrano in your environment? Share with us in the comments!

2 thoughts on “Deploying with Capistrano

  1. I’ve used capistrano for over two years and it did not fail me in it’s basic operations.

    Only, if you want to extend it, then you will have fun with it’s code base. But that’s another story…

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.