Notes about Capistrano, a website deployment tool.
Multi stage
core
http://www.capify.org/index.php/Multiple_Stages_Without_Multistage
# Default is to deploy development environment to staging directory.
set :rails_env, 'development'
set :deploy_to, "/var/www/#{application}/staging"
task :production do # Use with 'cap production deploy:setup' etc.
set :rails_env, 'production'
set :deploy_to, "/var/www/#{application}/production"
end
capistrano-ext
Rsync Strategy
This uses the capistrano_rsync_with_remote_cache gem to provide a strategy called rsync_with_remote_cache which does a local clone/checkout of repos into .rsync_cache then rsyncs to server.
Local
deploy.rb:
#############################################################
# Application
#############################################################
set :application, "mysite"
set :deploy_to, "/var/www/#{application}"
#############################################################
# Settings
#############################################################
set :use_sudo, false
set :rails_env, 'development'
ssh_options[:port] = '4998'
#############################################################
# Servers
#############################################################
set :user, "bn"
set :domain, "thedomain"
role :app, domain
role :web, domain
role :db, domain, :primary => true
#############################################################
# Git
#############################################################
set :repository, "~/projects/mysite/dev/mysite"
set :scm, :git
set :branch, "master"
set :deploy_via, :rsync_with_remote_cache
set :rsync_options, '-az --delete --exclude=.git --exclude=.gitignore --delete-excluded'
#############################################################
# Override Tasks
#############################################################
before 'deploy:symlink', 'remote:protect_database_config'
namespace :deploy do
task :finalize_update, :except => { :no_release => true } do
logger.info 'do nothing - overridden finalize_update'
end
desc "Restarting mod_rails with restart.txt"
task :restart, :roles => :app, :except => { :no_release => true } do
run "touch #{current_path}/tmp/restart.txt"
end
[:start, :stop].each do |t|
desc "#{t} task is a no-op with mod_rails"
task t, :roles => :app do
end
end
end
namespace :remote do
desc 'Protect database config'
task :protect_database_config, :roles => :app do
print " protecting database config\n"
run "chmod 600 #{release_path}/config/database.yml"
end
end
def do_system(command)
logger.debug(command)
system(command)
end
To use:
cap deploy:setup
cap deploy
Git Push Strategy
My version of a “git push” strategy, before I read about the various other more complete ones that have now been written (just search the internet for ‘capistrano push strategy’). A local repos is pushed to a remote repos which is used by Capistrano’s core remote_cache strategy to retrieve the files for deploy.
Remote
mkdir /var/www/mysite
cd /var/www/mysite
mkdir ~/myrepo
cd ~/myrepo
git init
Local
cd myrepo
git remote add deployserver ssh://myuser@myserver.com/~/myrepo
capify .
deploy.rb:
...
set :use_sudo, false
...
set :scm, :git
set :repository, 'myuser@myserver.com:/~/myrepo'
set :branch, 'master'
set :deploy_via, :remote_cache
set :scm_verbose, true
before 'deploy', 'local:push'
namespace :local do
desc 'Push local changes upstream'
task :push do
print 'Pushing local changes upstream'
do_system 'git push deployserver master'
end
end
def do_system(command)
logger.debug(command)
system(command)
end
cap deploy:setup
cap deploy
Passwords
If you add your local’s public key to remote then you won’t need to provide a password when you connect. If you have the repository set to the same server as remote, you will also need to add the remote’s public key to remote, as capistrano will attempt to connect to remote from remote!
Note that :repository is used by both local and remote so you can’t set it to myuser@localhost.