Installing gems with capistrano

Friday, March 16

Ever go to deploy a copy of your application and realize that you don’t have all the required gems installed? This is what I do to handle such a precarious situation via capistrano.


desc 'Installs required gems for this application'
task :install_gems, :roles => :app do
  # Add all gems required by your application here
  gems = %w(
    aws-s3
    libxml-ruby
    redcloth
    tzinfo
  )

  sudo "gem install -y --no-rdoc --no-ri #{gems.join(' ')}" do |channel, stream, data|
    print data if stream == :out
    channel.send_data($stdin.gets) if data =~ /^>\s/
  end
end

The channel.send bit is so you can respond to gems that have multiple versions available (i.e., mongrel). I’m also skipping rdoc and ri for this since I generally don’t care about having the documentation on the production server and it’s a bit faster when you skip them.

Oh, and if you wanted this to happen automatically after your cap setup, you could invoke it using (wait for it) the after_setup callback.

I’m sure there are improvements that could be made to this code, so suggestions are welcome.