Your SlideShare is downloading. ×
Making Your Capistrano Recipe Book
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Introducing the official SlideShare app

Stunning, full-screen experience for iPhone and Android

Text the download link to your phone

Standard text messaging rates apply

Making Your Capistrano Recipe Book

17,699
views

Published on

Talk given at January 2010 Sydney RORO (Ruby on Rails Oceania) meeting.

Talk given at January 2010 Sydney RORO (Ruby on Rails Oceania) meeting.

Published in: Technology, Business

0 Comments
12 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
17,699
On Slideshare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
116
Comments
0
Likes
12
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Making Your Capistrano Recipe Book Tim Riley @timriley
  • 2. development: oauth_consumer_key: secret_oauth_thing oauth_consumer_secret: secret_oauth_thing namespace :gems do oauth_callback: "http://decafsucks.com/oauth_callback" task :install, :roles => :app do # App <<: *base sudo "sh -c 'cd #{release_path} && sudo RAILS_ENV=production rake gems:install'" set :application, "decafsucks" end test: &test end # Server oauth_consumer_key: secret_oauth_thing set :user, 'deployer' oauth_consumer_secret: secret_oauth_thing namespace :db do set :deploy_to, "/home/deployer/deployments/#{application}" oauth_callback: "http://decafsucks.com/oauth_callback" task :generate_yaml, :roles => :app do set :use_sudo, false <<: *base db_config = <<-EOF set :port, '2222' base: &base production: adapter: mysql role :app, '192.168.0.1' oauth_consumer_key: secret_oauth_thing encoding: utf8 role :web, '192.168.0.1' oauth_consumer_secret: secret_oauth_thing username: mysql_user role :db, '192.168.0.1', :primary => true oauth_callback: "http://decafsucks.com/oauth_callback" password: #{db_password} <<: *base socket: /var/run/mysqld/mysqld.sock # Other EOF set :db_password, Proc.new { Capistrano::CLI.password_prompt('DB password: ')} run "mkdir -p #{shared_path}/config" development: put twitter_config, "#{shared_path}/config/twitter_auth.yml" database: decafsucks_development # SCM end <<: *base set :scm, :git set :repository, 'git@somehwere.com/myapp.git' desc 'Make symlink for database yaml' test: &test set :branch, 'master' task :symlink, :roles => :app do database: decafsucks_test set :deploy_via, :remote_cache run "ln -nfs #{shared_path}/config/twitter_auth.yml #{release_path}/co <<: *base end default_run_options[:pty] = true end rumble: set :ssh_options, { :forward_agent => true } database: decafsucks_production namespace :sphinx do <<: *base # Passenger desc 'Create a directory to store the sphinx indexes' namespace :deploy do task :create_db_dir, :roles => :app do production: desc "Restarting mod_rails with restart.txt" run "mkdir -p #{shared_path}/sphinx" database: decafsucks_production task :restart, :roles => :app, :except => { :no_release => true } do end <<: *base run "touch #{current_path}/tmp/restart.txt" EOF end desc 'Generate a config yaml in shared path' run "mkdir -p #{shared_path}/config" task :generate_yaml, :roles => :app do put db_config, "#{shared_path}/config/database.yml" [:start, :stop].each do |t| sphinx_yaml = <<-EOF end desc "#{t} task is a no-op with mod_rails" development: &base task t, :roles => :app do ; end morphology: stem_en desc 'Make symlink for database yaml' end config_file: #{shared_path}/config/sphinx.conf task :symlink, :roles => :app do end test: run "ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml" <<: *base end before 'deploy:setup', 'db:generate_yaml' production: end before 'deploy:setup', 'twitter:generate_yaml' <<: *base before 'deploy:setup', 'sphinx:create_db_dir' EOF namespace :twitter do before 'deploy:setup', 'sphinx:generate_yaml' run "mkdir -p #{shared_path}/config" task :generate_yaml, :roles => :app do put sphinx_yaml, "#{shared_path}/config/sphinx.yml" twitter_config = <<-EOF after 'deploy:update_code', 'db:symlink' end base: &base after 'deploy:update_code', 'twitter:symlink' desc 'Symlink the sphinx yml and config files, and the db directory for strategy: oauth after 'deploy:update_code', 'sphinx:symlink' task :symlink, :roles => :app do base_url: "https://twitter.com" run "ln -nfs #{shared_path}/sphinx #{release_path}/db/sphi authorize_path: "/oauth/authenticate" # after 'deploy:update_code', 'gems:install' run "ln -nfs #{shared_path}/config/sphinx.yml #{release_path}/config/ api_timeout: 10 run "ln -nfs #{shared_path}/config/sphinx.conf #{release_path}/config/ remember_for: 14 # days end end
  • 3. set :application, "decafsucks" set :user, 'deployer' set :deploy_to, "/home/deployer/deployments/#{application}" set :use_sudo, false role :app, '192.168.0.1' role :web, '192.168.0.1' role :db, '192.168.0.1', :primary => true set :scm, :git set :repository, 'git@git.mycorp.net:decafsucks.git’ set :branch, 'master' set :deploy_via, :remote_cache default_run_options[:pty] = true set :ssh_options, { :forward_agent => true }
  • 4. namespace :deploy do 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
  • 5. before 'deploy:setup', 'sphinx:create_db_dir' before 'deploy:setup', 'sphinx:generate_yaml' after 'deploy:update_code', 'sphinx:symlink' namespace :sphinx do desc 'Create a directory to store the sphinx indexes' task :create_db_dir, :roles => :app do run "mkdir -p #{shared_path}/sphinx" end desc 'Generate a config yaml in shared path' task :generate_yaml, :roles => :app do sphinx_yaml = <<-EOF development: &base morphology: stem_en config_file: #{shared_path}/config/sphinx.conf test: <<: *base production: <<: *base EOF run "mkdir -p #{shared_path}/config" put sphinx_yaml, "#{shared_path}/config/sphinx.yml" end desc 'Symlink the sphinx yml and config files, and the db directory for storage of indexes' task :symlink, :roles => :app do run "ln -nfs #{shared_path}/sphinx #{release_path}/db/sphinx" run "ln -nfs #{shared_path}/config/sphinx.yml #{release_path}/config/sphinx.yml" run "ln -nfs #{shared_path}/config/sphinx.conf #{release_path}/config/sphinx.conf" end end
  • 6. configuration = Capistrano::Configuration.respond_to?(:instance) ? Capistrano::Configuration.instance(:must_exist) : Capistrano.configuration(:must_exist) configuration.load do # stuff here... end
  • 7. unless Capistrano::Configuration.respond_to?(:instance) abort "capistrano/ext/multistage requires Capistrano 2" end Capistrano::Configuration.instance.load do # stuff here... end
  • 8. base.rb configuration.load do # User details _cset :user, 'deployer' _cset(:group) { user } # Application details _cset(:app_name) { abort "Specify the short name of your app, set :app_name, 'foo'" } set(:application) { "#{app_name}.mycorp.com" } _cset(:runner) { user } _cset :use_sudo, false # SCM settings _cset(:appdir) { "/home/#{user}/deployments/#{application}" } _cset :scm, 'git' set(:repository) { "git@git.mycorp.com:#{app_name}.git"} _cset :deploy_via, 'remote_cache' set(:deploy_to) { appdir } # Git settings for capistrano default_run_options[:pty] = true ssh_options[:forward_agent] = true end
  • 9. common.rb def _cset(name, *args, &block) unless exists?(name) set(name, *args, &block) end end
  • 10. base.rb configuration.load do # User details _cset :user, 'deployer' _cset(:group) { user } # Application details _cset(:app_name) { abort "Specify the short name of your app, set :app_name, 'foo'" } set(:application) { "#{app_name}.mycorp.com" } _cset(:runner) { user } _cset :use_sudo, false # SCM settings _cset(:appdir) { "/home/#{user}/deployments/#{application}" } _cset :scm, 'git' set(:repository) { "git@git.mycorp.com:#{app_name}.git"} _cset :deploy_via, 'remote_cache' set(:deploy_to) { appdir } # Git settings for capistrano default_run_options[:pty] = true ssh_options[:forward_agent] = true end
  • 11. require 'capistrano/mycorp/common' configuration.load do _cset(:app_name) { abort "Specify the short name of your app, set :app_name, 'foo'" } before 'deploy:setup', 'sphinx:create_db_dir' before 'deploy:setup', 'sphinx:generate_yaml' after 'deploy:update_code', 'sphinx:symlink' namespace :sphinx do desc 'Create a directory to store the sphinx indexes' task :create_db_dir, :roles => :app do run "mkdir -p #{shared_path}/sphinx" thinking_ end desc 'Generate a config yaml in shared path' task :generate_yaml, :roles => :app do sphinx_yaml = <<-EOF development: &main_settings config_file: #{shared_path}/config/sphinx.conf sphinx.rb pid_file: #{shared_path}/pids/sphinx.pid production: <<: *main_settings EOF put sphinx_yaml, "#{shared_path}/config/sphinx.yml" end desc 'Symlink the sphinx yml and config files, and the db directory for storage of indexes' task :symlink, :roles => :app do run "ln -nfs #{shared_path}/sphinx #{release_path}/db/sphinx" run "ln -nfs #{shared_path}/config/sphinx.yml #{release_path}/config/sphinx.yml" run "ln -nfs #{shared_path}/config/sphinx.conf #{release_path}/config/sphinx.conf" end end end
  • 12. Rakefile begin require 'jeweler' Jeweler::Tasks.new do |gemspec| gemspec.name = "capistrano-mycorp" gemspec.summary = "MyCorp recipes for Capistrano" gemspec.description = "MyCorp recipes for Capistrano" gemspec.email = "tim@openmonkey.com" gemspec.homepage = "http://github.com/timriley/capistrano-mycorp" gemspec.authors = ["Tim Riley"] end rescue LoadError puts "Jeweler not available. Install it with: gem install jeweler" end
  • 13. echo "0.0.1" > VERSION rake gemspec rake build jeweler --help
  • 14. set :application, "decafsucks" set :user, 'deployer' set :deploy_to, "/home/deployer/deployments/#{application}" namespace :sphinx do set :use_sudo, false desc 'Create a directory to store the sphinx indexes' task :create_db_dir, :roles => :app do role :app, '192.168.0.1' run "mkdir -p #{shared_path}/sphinx" role :web, '192.168.0.1' end role :db, '192.168.0.1', :primary => true desc 'Generate a config yaml in shared path' set :scm, :git task :generate_yaml, :roles => :app do set :repository, 'git@git.mycorp.net:decafsucks.git' sphinx_yaml = <<-EOF set :branch, 'master' development: &base set :deploy_via, :remote_cache morphology: stem_en config_file: #{shared_path}/config/sphinx.conf default_run_options[:pty] = true test: set :ssh_options, { :forward_agent => true } <<: *base production: namespace :deploy do <<: *base desc "Restarting mod_rails with restart.txt" EOF task :restart, :roles => :app, :except => { :no_release => true } do run "mkdir -p #{shared_path}/config" run "touch #{current_path}/tmp/restart.txt" put sphinx_yaml, "#{shared_path}/config/sphinx.yml" end end [:start, :stop].each do |t| desc 'Symlink the sphinx yml and config files, and the db directory for storage of indexes' desc "#{t} task is a no-op with mod_rails" task :symlink, :roles => :app do task t, :roles => :app do ; end run "ln -nfs #{shared_path}/sphinx #{release_path}/db/sphinx" end run "ln -nfs #{shared_path}/config/sphinx.yml #{release_path}/config/sphinx.yml" end run "ln -nfs #{shared_path}/config/sphinx.conf #{release_path}/config/sphinx.conf" end before 'deploy:setup', 'sphinx:create_db_dir' end before 'deploy:setup', 'sphinx:generate_yaml' after 'deploy:update_code', 'sphinx:symlink'
  • 15. set :app_name, 'decafsucks' role :app, '192.168.0.1' role :web, '192.168.0.1' role :db, '192.168.0.1', :primary => true require 'capistrano/mycorp/base' require 'capistrano/mycorp/thinking_sphinx'
  • 16. ★ Multistage defaults ★ Mounting shares ★ web:disable ★ Gem installation ★ Gem bundling ★ Populating config.yml ★ Populating database.yml ★ Thinking Sphinx ★ ...
  • 17. Thank You! @timriley openmonkey.com timriley/capistrano-mycorp technicalpickles/jeweler