What is Capistrano?
Capistrano is a remote server automation tool.
It supports the scripting and execution of arbitrary tasks, and includes a set of sane-default deployment workflows.
Capistrano can be used to:
- Reliably deploy web application to any number of machines simultaneously, in sequence or as a rolling set
- To automate audits of any number of machines (checking login logs, enumerating uptimes, and/or applying security patches)
- To script arbitrary workflows over SSH
- To automate common tasks in software teams.
- To drive infrastructure provisioning tools such as chef-solo, Ansible or similar.
Capistrano is also very scriptable, and can be integrated with any other Ruby software to form part of a larger tool.
What does it look like?
What else is in the box?
There’s lots of cool stuff in the Capistrano toy box:
- Interchangeable output formatters (progress, pretty, html, etc)
- Easy to add support for other source control management software.
- A rudimentary multi-console for running Capistrano interactively.
- Host and Role filters for partial deploys, or partial-cluster maintenance.
- Recipes for the Rails asset pipelines, and database migrations.
- Support for complex environments.
- A sane, expressive API:
desc "Show off the API"
task :ditty do
on roles(:all) do |host|
# Capture output from the remote host, and re-use it
# we can reflect on the `host` object passed to the block
# and use the `info` logger method to benefit from the
# output formatter that is selected.
uptime = capture('uptime')
if host.roles.include?(:web)
info "Your webserver #{host} has uptime: #{uptime}"
end
end
on roles(:app) do
# We can set environmental variables for the duration of a block
# and move the process into a directory, executing arbitrary tasks
# such as letting Rails do some heavy lifting.
with({:rails_env => :production}) do
within('/var/www/my/rails/app') do
execute :rails, :runner, 'MyModel.something'
end
end
end
on roles(:db) do
# We can even switch users, provided we have support on the remote
# server for switching to that user without being prompted for a
# passphrase.
as 'postgres' do
widgets = capture "echo 'SELECT * FROM widgets;' | psql my_database"
if widgets.to_i < 50
warn "There are fewer than 50 widgets in the database on #{host}!"
end
end
end
on roles(:all) do
# We can even use `test` the way the Unix gods intended
if test("[ -d /some/directory ]")
info "Phew, it's ok, the directory exists!"
end
end
end