RailsConf: Mike Clark -- Introduction to Capistrano

Posted by Nick Sieger Fri, 23 Jun 2006 16:45:00 GMT

Introduction to Capistrano

Mike Clark has been Java-free for 15 months and 16 days. He’s here to talk about deployment with Capistrano.

First off, props to Jamis! There are several hundred people in the room and it’s a tribute to him.

Capistrano is about making it easy to deploy web applications. “Cap”, the short name has quickly become jargon in the Rails community. “Stop wasting time, just cap it!”

Capistrano is built to scale. From a single machine all the way up to clusters, it is intended to make application deployment as simple as the push of a button. That’s priceless for reducing friction as your project nears its first production live date, as well as subsequent maintenance releases.

Configuring Capistrano - create a recipe

Set the application name

set :application, "depot"

Set the repository

set :repository, "http://svn.yourhost.com/#{application}/trunk"

Roles

role :app, "app01.example.com", "app02.example.com"
role :web, "web01.example.com", "web02.example.com"
role :db, "db.example.com", :primary => true

Deployment Root

set :deploy_to, "/Library/Rails/#{application}"

Setup

Run cap setup once to setup the deployment directory structure on all the roles you’ve configured:

depot
  `- releases
  `- shared
       `- log
       `- system

First time deploy

Run cap update_code symlink. This checks out the code, adds a “current” symlink to the code on the remote machine that points to the timestamped releases directory where the code was checked out. You can then manually start your web server(s) if you wish.

New Release

Run cap deploy. The newly committed code to your repository gets pulled, a new release created, and it also restarts fcgi processes.

Rollback release

Run cap rollback. The “current” symlink gets updated to the previous release, and the fcgi processes get restarted.

Scheduled downtime

Run cap disable_web. A maintenance screen is put up during the maintenance period. This is great when you’re in firefighting mode and you don’t want to think, just get the page up there. To enable again, use cap enable_web.

Customization

Here are examples of several useful, real-world tasks. The fourth task shows aggregation of tasks together.

desc "locate ruby"
task :which_ruby, :roles => [:app] do
  puts "You're running:"
  run "which ruby"
end

task :current_revision do
  run "echo Current rev is #{revision}"
  run "echo Current rev is at #{releast_path}"
end

task :uptime, :roles => [:app, :web, :db] do
  run "uptime"
end

task :status do 
  which_ruby
  current_revision
  uptime
end

Channels and streams

Mike showed a log file tailing task here. I failed to capture the full task code, so you’re on your own here.

Hooks

task :before_deploy, :roles => [:app] do
  cleanup
end

task :after_update_code, :roles => [:app] do
  production_config = "path/to/database.yml"
  run "cp #{production_config} #{current_path}/config/database.yml"
end

Multiple configs

if where == "production"
  set :user, "ops_gal"
else
  set :user, "dev_guy"
end

Task libraries

You can creat a file full of extra, reusable tasks and simply require them in. The files can be published and installed as gems or placed anywhere on your load path.

Capistrano isn’t just for Rails

It’s great at shuttling files around and executing remote commands on the server. Mike describes some automation James Duncan Davidson did to replicate new servers into a cluster with the push of a button.

Assumptions

Capistrano, out of the box comes with some assumptions:

  • Remote servers talk POSIX
  • Same deploy structure and password on each machine
  • Web application uses FastCGI with Apache or Lighty

It looks like you can bend some of these assumptions if you are willing to write your own custom deployment tasks.

Take Home

Capistrano provides easy, consistent, worry-free deployment of new releases. The friction to deploying your app just got simpler, so you can go enjoy your life!

Notes and Questions

  • Can you use SSH public keys to authenticate? Yes, this is the most typical scenario.
  • You can use sudo to execute remote commands -- this is built-in.
  • Can you/would you want to check out subsets of files on each server, rather than pulling all the code everywhere? So far most of our stuff has been on the same server, so this hasn’t been an issue. It seems like you would need to override deployment tasks for some roles.
  • Sometimes I want to deploy a lot, but what if the app is big, lots of media files? It can take a longer time to pull all the code. One solution I’ve seen is to check out once and rsync everywhere else. I haven’t had to do that myself.
  • Who can I talk to for promoting my own extensions into Capistrano. You probably don’t. Instead, publish your extensions, blog them, and see if it takes.
  • deploy_with_migrations -- use with caution as it’s not as easy to rollback, and not all migrations can be rolled back cleanly.

Posted in ,  | Tags  | no comments | no trackbacks

Comments

Trackbacks

Use the following link to trackback from your own site:
http://blog.nicksieger.com/articles/trackback/23