Deploy Drupal With Capistrano A Year Later - Presentation Transcript
Deploy Drupal with
Capistrano
a year later
“A life without philosophy
Capistrano is not worth living”
--Socrates
“A life without philosophy
Capistrano is not worth living”
--Socrates
“Drupal is worth the PHPain”
--Anonymous from Bari
The Actors
Our friend
Our friend
Kick Ass CMS
Our friend
Kick Ass CMS
Isn’t very deploy friendly
Our friend
Kick Ass CMS
Isn’t very deploy friendly
and needs some help...
His friend
Kick Ass CMS
His friend
Kick Ass CMS
The logo sucks
His friend
Kick Ass CMS
The logo sucks
but it will help your deployments!
The Target
$ cap intinig production deploy
capistrano
$ cap intinig production deploy
capistrano
$ cap intinig production deploy
developer
capistrano stage
$ cap intinig production deploy
developer
capistrano stage
$ cap intinig production deploy
developer command
The Code
Capfile
where the fun starts
load 'deploy' if respond_to?(:namespace) # cap2 differentiator
load 'includes/recipes/stages'
load 'includes/recipes/mikamai'
load 'includes/recipes/drupal'
load 'includes/recipes/overrides'
load 'includes/recipes/devs'
# SCM Stuff configure to taste, just remember the repository
set :repository, "git@github.com:mikamai/app.git"
set :scm, :git
set :branch, "master"
set :repository_cache, "git_master"
set :deploy_via, :remote_cache
set :scm_verbose, true
set :keep_releases, 3
includes/recipes
where we put the “Good Stuff”™
devs.rb
let’s tell capistrano about ourselves
task :intinig do
set :local_mysqldump, "/usr/local/mysql/bin/mysqldump"
set :local_db_user, "root"
set :local_db_password, "youwishItoldyou"
set :local_db_name, "app_db"
end
task :paolo do
set :local_mysqldump, "/Applications/MAMP/Library/bin/mysqldump"
set :local_db_user, "root"
set :local_db_password, "paolo"
set :local_db_name, "stefano"
end
drupal.rb
change capistrano default behavior
load File.dirname(__FILE__) + '/drupal/db'
load File.dirname(__FILE__) + '/drupal/configure'
after 'deploy:setup', 'drupal:setup'
after 'deploy:symlink', 'drupal:symlink'
before 'deploy:start', 'drupal:db:import:production'
before 'deploy:restart', 'drupal:configure:stage'
before 'deploy:start', 'drupal:configure:stage'
namespace :drupal do
task :setup, :except => { :no_release => true } do
sudo "mkdir -p #{shared_path}/files"
sudo "chmod a+w #{shared_path}/files"
sudo "mkdir -p #{shared_path}/dumps"
sudo "chown -R #{user}:#{user} #{deploy_to}"
end
task :symlink, :except => { :no_release => true } do
sudo "ln -s #{shared_path}/files #{latest_release}"
end
end
drupal/configure.rb
a small hack for multiple stages
namespace :drupal do
namespace :configure do
task :stage do
source = "#{latest_release}/sites/default/settings.#{stage_name}.php"
dest = "#{latest_release}/sites/default/settings.php"
sudo "cp #{source} #{dest}"
end
end
end
drupal/db.rb
mysql grinding
namespace :local do
desc "Dumps the local database"
task :default, :roles => :db do
raise RuntimeError.new("failed dump") unless system "#{local_mysqldump} -u #{local_db_user} --
password=#{local_db_password} #{local_db_name} > dump.local.sql"
end
namespace :upload do
desc "Dumps and uploads the local database"
task :default do
drupal::db::dump::local::default
put(File.read("dump.local.sql"), "#{shared_path}/dumps/dump.local.sql")
run "mysql -u #{db_user} --password=#{db_password} #{db_name} < #{shared_path}/dumps/
dump.local.sql"
end
end
end
drupal/db.rb
mysql grinding / 2
namespace :remote do
desc "Dumps the remote database"
task :default, :roles => :db do
filename = "#{Time.now.to_i.to_s}.dump.sql"
run "cd #{shared_path}/dumps; #{remote_mysqldump} -u #{db_user} --password=#{db_password}
#{db_name} > #{filename}"
run "cd #{shared_path}/dumps; bzip2 #{filename}"
end
namespace :download do
desc "Dumps and downloads the remote database"
task :default do
drupal::db::dump::remote::default
latest
end
desc "Downloads the latest database dump"
task :latest, :roles => :db do
dumps = capture("ls -xt #{shared_path}/dumps").split.reverse
get("#{shared_path}/dumps/#{dumps.last}", "./#{dumps.last}")
end
end
end
mikamai.rb
fix problems on our servers
before 'deploy:restart', 'mikamai:permissions:fix'
before 'deploy:start', 'mikamai:permissions:fix'
namespace :mikamai do
namespace :production do
task :symlink, :except => { :no_release => true } do
sudo "rm -rf /var/www/#{application}"
sudo "ln -s #{latest_release} /var/www/#{application}"
end
end
namespace :permissions do
task :fix, :except => { :no_release => true } do
sudo "chown -R www-data:www-data #{latest_release}"
end
end
end
overrides.rb
do as we say not as we do
namespace :deploy do
task :finalize_update, :except => { :no_release => true } do
sudo "chmod -R g+w #{latest_release}" if fetch(:group_writable, true)
end
task :cold do
update
start
end
task :restart do
end
task :start do
end
end
stages.rb
one for everyone
set :application, "cool_app"
desc "deploy to development environment"
task :development do
set :stage_name, "development"
role :web, "danton.mikamai.com:8888", :primary => true
role :db, "danton.mikamai.com:8888", :primary => true
set :user, "drupal"
set :password, "secret"
set :remote_mysqldump, "/usr/bin/mysqldump"
set :deploy_to, "/var/apps/#{application}"
set :db_user, "dbuser"
set :db_password, "supersecret"
set :db_name, "appname"
end
0 comments
Post a comment