Using Capistrano

“We will encourage you to develop the three great virtues of a programmer: laziness, impatience, and hubris.”—Larry Wall, Programming Perl

For most programmers, deployment is an area that could do with a touch
of laziness. Deploying to a cluster—or even one machine—can
be
repetitive and tiring.
Enter Capistrano, a Ruby deployment tool that makes the task of deploying
an application to servers easier by running defined tasks for you on
the remote servers.

The Ruby programmers' toolbox contains so many tools for eliminating most
of their work, it's fair to say that Ruby programmers are probably some
of the laziest. If having all the boring jobs done for you isn't enough,
Ruby programmers even contrive to have most of their tools built in one
language—Ruby. No bash-make-PHP-Perl combinations. It's all Ruby.

Think of Capistrano as a build system that specializes in running
commands remotely on any number of machines. If you have to connect to
a half-dozen machines to push updates, or have no quick-and-easy
way of rolling back the entire cluster if (or when?) something goes
wrong, you need to be a little more lazy.

Capistrano groups tasks in recipes, and the default recipe, which we'll
look at in a moment, is very geared toward Rails, running migrations
and restarting the Rails server. However, Capistrano's core is not
Rails-specific. You can build your own recipes for all your dullest tasks,
and you can tweak the Rails recipe to work with whichever language or
framework you're using.

Let's take a look at what Capistrano does for Rails deployment, how
to build your own tasks and how to push your own application out to 20
servers with just one command.

Capistrano and Rails

Like Rails, Capistrano increasingly is deployed with flavours of Linux
and is installed by default in Leopard, so you might not even have to
install it. If you do need to, installing Capistrano is as easy as
any Ruby gem. Simply run:

sudo gem install -y capistrano

Capistrano has two main commands: cap, which is used for viewing and
running the tasks, and capify, which is used to set up a Rails project
for use with Capistrano. Assuming you have a Rails project, grab a copy
of it, and run capify at the project root:

cd path/to/project capify .

This creates just two files: Capfile and config/deploy.rb. Capfile
is to Capistrano as Makefile is to make and Rakefile is to rake.
Capistrano expects a Capfile to be present and to contain the tasks or
to include a Ruby file that does.

In this case, the Capfile just includes config/deploy.rb, so the latter
is the one of interest. The deploy file contains a bunch of settings
you need to take care of before running cap, starting with:

If you aren't used to Ruby's syntax, this all will look deceptively
like simple configuration. However, because you don't have to use
brackets when calling functions in Ruby, each line actually is a call to
the set() function in Capistrano's core:

set(:application, "your-app-name")

Set the :application variable to a name without spaces—this will be
used to create a deployment directory later. Set :repository to your
versioning repository's URL (in this example, we use SVN).

If you have a user name and password for SVN, set them with the lines:

set :scm_username, "svn-username"
set :scm_password, "svn-password"

Then, uncomment and set the deployment directory. If the deploy_to
doesn't exist on your deployment server, Capistrano creates it:

set :deploy_to, "/path/to/doc/root/www/#{application}"

Here, we're using the application variable we set previously to set part
of the deploy_to variable. This is all standard Ruby syntax, available
in all Capistrano scripts, making this way of working extremely powerful
and a little less cumbersome than a hodge-podge of obscure syntaxes.

Finally, we need to set the servers that will host the deployment. You
can add as many servers as you like, and the server name just has to
be something that SSH understands—for example:

If you're just testing out Capistrano, it's worth setting the
deployment location as your working machine; that way, you can learn without
moving between machines:

role :app, "me@my-local-ip"

Now we're ready to ask Capistrano to set up the deployment location using
the command:

cap deploy:setup

When you run this, Capistrano starts showing you what it's doing. This
helps when debugging Capfiles, and it reassures you that you're doing the
right thing. Whenever you connect to another server, you'll be prompted
for the password, as usual, after which Capistrano will run a bunch of
other commands.

After deploy:setup, the deployment directory now contains some extra
directories that will allow cap to push new versions, do rollbacks and
so on:

myapp/
releases/ shared/log shared/pids shared/system

Next, we get on and deploy the application. Capistrano will check out
the source, put it into releases and create a symlink to it called
current:

cap deploy:cold

After this has run, take another look in the deployment location:

# current@ -> /www/captest/myapp/releases/20080614144520

This a “cold” deployment, meaning tasks that are one-time tasks are
run. To deploy the application in the future, you simply use the deploy
task:

cap deploy

When you've run either deploy:cold or deploy, have a look in
the deployment directory and find where your source code fits into
Capistrano's way of deploying things.

The deploy task replaces logging in to the server, getting the source,
setting up any databases and restarting the servers. Run it a few times,
and get used to that lazy feeling!