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.