Capistrano

Deploying rails applications with capistrano

Here is the example deploy.rb for crabgrass

codetitle. config/deploy.rb

#
# REMEMBER: you can see available tasks with "cap -T"
#

set :application, "crabgrass"

# deploy with git
set :repository,  "gitosis@labs.riseup.net:werise"
set :scm, "git"

set :local_repository, "#{File.dirname(__FILE__)}/../"

# if your server has git installed
set :deploy_via, :remote_cache  
set :git_shallow_clone, 1  # only copy the most recent, not the entire repository (default:1)  

# if you server does not have git. 
#set :deploy_via, :copy 
#set :copy_strategy, :checkout
#set :copy_exclude, [".git"]
#set :branch, 'master'

set :keep_releases, 3
set :use_sudo, false   

role :web, "we.riseup.net"
role :app, "we.riseup.net"
role :db, "we.riseup.net", :primary=>true

set :deploy_to, "/usr/apps/#{application}" 
set :user,      'crabgrass'

set :app_db_host, 'localhost'
set :app_db_user, 'crabgrass'
set :app_db_pass, 'xxxxxxxxx'

# =============================================================================
# SSH OPTIONS
# =============================================================================
# ssh_options[:keys] = %w(/path/to/my/key /path/to/another/key)
# ssh_options[:port] = 25
set :ssh_options, { :forward_agent => true, :paranoid => false }

# =============================================================================
# TASKS
# =============================================================================

##
## CREATING DATABASE.YML
##

# inspired by http://www.jvoorhis.com/articles/2006/07/07/managing-database-yml-with-capistrano

def database_configuration(db_role)
%Q[
login: &login
  adapter: mysql
  encoding: utf8
  host: #{eval(db_role+"_db_host")}
  username: #{eval(db_role+"_db_user")}
  password: #{eval(db_role+"_db_pass")}

development:
  database: #{application}_development
  <<: *login

test:
  database: #{application}_test
  <<: *login

production:
  database: #{application}
  <<: *login
]
end

##
## SETTING UP LINKS TO SHARED
##

namespace :crabgrass do

  # rerun after_setup if you change the db configuration
  desc "Create shared directories, update database.yml" 
  task :create_shared, :roles => :app do
    run "mkdir -p #{deploy_to}/#{shared_dir}/tmp/sessions"
    run "mkdir -p #{deploy_to}/#{shared_dir}/tmp/cache"
    run "mkdir -p #{deploy_to}/#{shared_dir}/tmp/sockets"
    run "mkdir -p #{deploy_to}/#{shared_dir}/avatars"
    run "mkdir -p #{deploy_to}/#{shared_dir}/assets"
    run "mkdir -p #{deploy_to}/#{shared_dir}/index"
    run "mkdir -p #{deploy_to}/#{shared_dir}/public_assets"
    run "mkdir -p #{deploy_to}/#{shared_dir}/latex"
    run "mkdir -p #{deploy_to}/#{shared_dir}/sphinx"
    run "mkdir -p #{deploy_to}/#{shared_dir}/config"
    run "mkdir -p #{deploy_to}/#{shared_dir}/bin"
    run "touch #{deploy_to}/#{shared_dir}/config/production.sphinx.conf"

    put database_configuration('app'), "#{deploy_to}/#{shared_dir}/config/database.yml" 
  end

  desc "Link in the shared dirs" 
  task :link_to_shared do
    run "rm -rf #{release_path}/tmp"
    run "ln -nfs #{shared_path}/tmp #{release_path}/tmp"
    
    run "rm -rf #{release_path}/index"
    run "ln -nfs #{shared_path}/index #{release_path}/index"

    run "rm -rf #{release_path}/assets"
    run "ln -nfs #{shared_path}/assets #{release_path}/assets"

    run "rm -rf #{release_path}/public/assets"
    run "ln -nfs #{shared_path}/public_assets #{release_path}/public/assets"
      
    run "rm -rf #{release_path}/public/avatars"
    run "ln -nfs #{shared_path}/avatars #{release_path}/public/avatars"
    
    run "rm -rf #{release_path}/public/latex"
    run "ln -nfs #{shared_path}/latex #{release_path}/public/latex"

    run "rm -rf #{release_path}/db/sphinx"
    run "ln -nfs #{shared_path}/sphinx #{release_path}/db/sphinx"
    run "touch #{shared_path}/config/production.sphinx.conf"
    run "ln #{shared_path}/config/production.sphinx.conf #{release_path}/config/production.sphinx.conf"

    run "ln -nfs #{deploy_to}/#{shared_dir}/config/database.yml #{release_path}/config/database.yml"
    run "ln -nfs #{deploy_to}/#{shared_dir}/css/favicon.ico #{release_path}/public/favicon.ico"
    run "ln -nfs #{deploy_to}/#{shared_dir}/css/favicon.png #{release_path}/public/favicon.png"
  end
end

after :deploy, "crabgrass:link_to_shared"
after :setup, "crabgrass:create_shared"


##
## PASSENGER (ie MOD_RAILS)
##

namespace :passenger do
  desc "Restart rails application"
  task :restart do
    run "touch #{current_path}/tmp/restart.txt"
  end

  # requires root
  desc "Check memory stats"
  task :memory do
    sudo "passenger-memory-stats"
  end

  # requires root
  desc "Check status of rails processes"
  task :status do
    sudo "passenger-status"
  end

end

after :deploy, "passenger:restart"

##
## SPHINX
##

namespace :ts do 
  desc "start sphinx searchd"
  task :start do
    set :rake_cmd, "ts:start" 
    rake_exec
  end

  desc "stop sphinx searchd"
  task :stop do
    set :rake_cmd, "ts:stop" 
    rake_exec
  end
end

##
## Some extra useful tasks
##

set :rake_cmd, (ENV['RAKE_CMD'] || nil)

desc "run rake remotely"
task :rake_exec do
  if rake_cmd
    run "cd #{current_path} && rake #{rake_cmd} RAILS_ENV=production"
  end
end

desc "Clear file-based fragment and/or page cache"
task :clear_cache do
  set :rake_cmd, "tmp:cache:clear" 
  rake_exec
end

desc "Update the gibberize database from the translation files."
task :load_translations do
  set :rake_cmd, "cg:l10n:load_translations"
  rake_exec
end

desc "Update the translation files from gibberize database."
task :extract_translations do
  set :rake_cmd, "cg:l10n:extract_translations"
  rake_exec
end
after :extract_translations, "passenger:restart"

desc "Download lang/*.yml files"
task :download_lang_files do
  run "cd #{current_path}"
  download "lang", "lang"
end

desc "Upload lang/*.yml files"
task :upload_lang_files do
  run "cd #{current_path}"
  upload "lang", "lang"
end