Created
November 27, 2012 12:16
-
-
Save tomdavies/4153939 to your computer and use it in GitHub Desktop.
Deploying ExpressionEngine 2 with Capistrano
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
set :deploy_to, "/var/www/default" | |
set :branch, 'master' | |
#Remote DB info | |
set :dbuser, "" | |
set :dbname, "" | |
set :dbhost, "" | |
set :dbpass, "" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
set :deploy_to, "/var/www/staging" | |
#Remote DB info | |
set :dbuser, "" | |
set :dbname, "" | |
set :dbhost, "" | |
set :dbpass, "" | |
# ask you which branch you want to deploy from (defaulting to the most recent tag) | |
set :branch do | |
puts `git branch`.split("\n").inspect | |
default_branch = `git branch`.split("\n").detect{|b| b =~ /^\* / }.gsub(/^\* /, '') | |
branch = Capistrano::CLI.ui.ask "Branch to deploy (make sure to push the branch first): [#{default_branch}] " | |
branch = default_branch if branch.empty? | |
branch | |
end | |
namespace :deploy do | |
desc "Stop bots from indexing the site" | |
task :deny_robots, :roles => :app do | |
robots = %q{#Disallow all robots | |
User-Agent: * | |
Disallow: / | |
} | |
put robots, "#{deploy_to}/current/public/robots.txt" | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
################################################################################ | |
# Capistrano recipe for deploying ExpressionEngine websites from Git # | |
# Adapted from starting point by Dan Benjamin - http://example.com/ # | |
# # | |
################################################################################ | |
#configure capistranp for multistage deployment | |
set :stages, %w(staging production local) | |
set :default_stage, "staging" | |
require 'capistrano/ext/multistage' | |
begin | |
require 'capistrano/ext/multistage' | |
rescue LoadError | |
puts 'Capistrano Extension not found' | |
puts 'sudo gem install capistrano-ext' | |
exit | |
end | |
# the application name | |
set :application, "myapp" | |
# the name hostname of the remote server | |
set :domain, "www.example.com" | |
set :port, 40012 | |
# the name of your system directory, which you may have customised | |
set :ee_system, "system/expressionengine" | |
# the git-clone url for your repository - branch is set in stage file | |
set :repository, "[email protected]:user/myapp.git" | |
# the name of the deployment user-account on the server | |
set :user, "deployuser" | |
set :runner, "deployuser" | |
set :use_sudo, true | |
default_run_options[:pty] = true | |
#custom ssh port number | |
#ssh_options[:port] = 28069 | |
#local development settings | |
set :local_dbhost, "" | |
set :local_dbuser, "" | |
set :local_dbname, "" | |
set :local_dbpass, "" | |
#directory for DB dumps | |
set :dump_directory, "db" | |
set :no_of_dumps_kept, "10" | |
#remote directory for uploads grab - relative to :deploy_to path | |
set :path_to_uploads_dir, "public/uploads" | |
set :path_to_assets_dir, "public/assets" | |
# SCM settings | |
set :scm, :git | |
#set :ssh_options, { :forward_agent => true } | |
set :deploy_via, :remote_cache | |
set :copy_strategy, :checkout | |
set :keep_releases, 5 | |
set :copy_compression, :bz2 | |
set :copy_exclude, [".git", ".gitignore"] | |
# Roles | |
role :app, domain | |
role :web, domain | |
role :db, domain, :primary => true | |
# Deployment process | |
after "deploy:setup", "deploy:makedirs" | |
after "deploy", "deploy:cleanup", "deploy:create_symlinks", "deploy:set_permissions" | |
# Custom deployment tasks | |
namespace :deploy do | |
desc "This is here to overide the original :restart" | |
task :restart, :roles => :app do | |
# do nothing but override the default | |
end | |
task :finalize_update, :roles => :app do | |
run "chmod -R g+w #{latest_release}" if fetch(:group_writable, true) | |
# override the rest of the default method | |
end | |
desc "Create additional EE directories and set permissions after initial setup" | |
task :makedirs, :roles => :app do | |
# create public directory | |
run "mkdir #{shared_path}/public" | |
# create upload directories | |
run "mkdir #{shared_path}/#{path_to_uploads_dir}" | |
run "mkdir #{shared_path}/#{path_to_uploads_dir}/files" | |
run "mkdir #{shared_path}/#{path_to_uploads_dir}/images" | |
run "mkdir #{shared_path}/#{path_to_uploads_dir}/images/banners" | |
run "mkdir #{shared_path}/#{path_to_uploads_dir}/images/banners/home" | |
run "mkdir #{shared_path}/#{path_to_uploads_dir}/images/banners/landing" | |
run "mkdir #{shared_path}/#{path_to_uploads_dir}/images/drivers" | |
run "mkdir #{shared_path}/#{path_to_uploads_dir}/images/events" | |
run "mkdir #{shared_path}/#{path_to_uploads_dir}/images/galleries" | |
run "mkdir #{shared_path}/#{path_to_uploads_dir}/images/modules" | |
run "mkdir #{shared_path}/#{path_to_uploads_dir}/images/news" | |
run "mkdir #{shared_path}/#{path_to_uploads_dir}/images/pages" | |
# set permissions on uploads dirs | |
run "chmod 755 #{shared_path}/#{path_to_uploads_dir}/files" | |
run "chmod 755 #{shared_path}/#{path_to_uploads_dir}/images" | |
run "chmod 755 #{shared_path}/#{path_to_uploads_dir}/images/banners" | |
run "chmod 755 #{shared_path}/#{path_to_uploads_dir}/images/banners/home" | |
run "chmod 755 #{shared_path}/#{path_to_uploads_dir}/images/banners/landing" | |
run "chmod 755 #{shared_path}/#{path_to_uploads_dir}/images/drivers" | |
run "chmod 755 #{shared_path}/#{path_to_uploads_dir}/images/events" | |
run "chmod 755 #{shared_path}/#{path_to_uploads_dir}/images/galleries" | |
run "chmod 755 #{shared_path}/#{path_to_uploads_dir}/images/modules" | |
run "chmod 755 #{shared_path}/#{path_to_uploads_dir}/images/news" | |
run "chmod 755 #{shared_path}/#{path_to_uploads_dir}/images/pages" | |
end | |
desc "Set the correct permissions for the config files and cache folder" | |
task :set_permissions, :roles => :app do | |
sudo "chmod -R 777 #{current_release}/#{path_to_assets_dir}/cache/" | |
sudo "chmod -R 777 #{current_release}/#{ee_system}/cache" | |
sudo "chmod -R 777 #{current_release}/#{path_to_uploads_dir}" | |
end | |
desc "Create symlinks to shared data such as config files and uploaded images" | |
task :create_symlinks, :roles => :app do | |
# upload directories | |
run "ln -s #{shared_path}/#{path_to_uploads_dir}/ #{current_release}/public/" | |
run "ln -s #{shared_path}/.htaccess #{current_release}/public/" | |
end | |
desc "Clear the ExpressionEngine caches" | |
task :clear_cache, :roles => :app do | |
sudo "if [ -e #{current_release}/#{ee_system}/cache/db_cache ]; then rm -r #{current_release}/#{ee_system}/cache/db_cache/*; fi" | |
sudo "if [ -e #{current_release}/#{ee_system}/cache/lg_cache ]; then rm -r #{current_release}/#{ee_system}/cache/lg_cache/*; fi" | |
sudo "if [ -e #{current_release}/#{ee_system}/cache/magpie_cache ]; then rm -r #{current_release}/#{ee_system}/cache/magpie_cache/*; fi" | |
sudo "if [ -e #{current_release}/#{ee_system}/cache/page_cache ]; then rm -r #{current_release}/#{ee_system}/cache/page_cache/*; fi" | |
sudo "if [ -e #{current_release}/#{ee_system}/cache/sql_cache ]; then rm -r #{current_release}/#{ee_system}/cache/sql_cache/*; fi" | |
sudo "if [ -e #{current_release}/#{ee_system}/cache/tag_cache ]; then rm -r #{current_release}/#{ee_system}/cache/tag_cache/*; fi" | |
end | |
end | |
namespace :db do | |
desc "Generates a name for the remote backup file" | |
task :backup_name do | |
now = Time.now | |
run "mkdir -p #{shared_path}/#{dump_directory}/" | |
backup_time = [now.year, now.month, now.day, now.hour, now.min, now.sec].join('-') | |
set :backup_file, "#{shared_path}/#{dump_directory}/#{dbname}-snapshot-#{backup_time}.sql" | |
end | |
desc "Dumps a database to dump folder" | |
task :dump do | |
backup_name | |
run "mysqldump --add-drop-table -u #{dbuser} -p #{dbname} | bzip2 -c > #{backup_file}.bz2" do |ch, stream, out| | |
ch.send_data "#{dbpass}\n" if out=~ /^Enter password:/ | |
end | |
end | |
#TODO rm cmd not working at the moment | |
desc "Cleans up remote dump folder" | |
task :cleanup do | |
run "cd /#{shared_path}/#{dump_directory}; (ls -t|head -n #{no_of_dumps_kept};ls)|sort|uniq -u|xargs rm" | |
end | |
desc "Generates a name for the local backup file" | |
task :local_backup_name do | |
now = Time.now | |
run_locally "mkdir -p #{dump_directory}/development" | |
backup_time = [now.year, now.month, now.day, now.hour, now.min, now.sec].join('-') | |
set :local_backup_file, "#{dump_directory}/development/#{local_dbname}-snapshot-#{backup_time}.sql" | |
end | |
desc "Performs a local db dump and bzips the result" | |
task :local_dump do | |
local_backup_name | |
run_locally "mysqldump --host=#{local_dbhost} --add-drop-table -u #{local_dbuser} -p#{local_dbpass} #{local_dbname} | bzip2 -c > #{local_backup_file}.bz2" | |
end | |
desc "Takes a passed remote sql dump and imports to local db" | |
task :import_dump do | |
run_locally "bzcat /tmp/#{application}.sql.bz2 | mysql --host=#{local_dbhost} -u #{local_dbuser} -p#{local_dbpass} #{local_dbname}" | |
end | |
#Sync dbs | |
desc "Dumps the DB from the specified stage, backs up the local DB and imports the remote dump" | |
task :to_local do | |
#remove old sql file if exists | |
if File.exist? "/tmp/#{application}.sql" | |
run_locally "rm /tmp/#{application}.sql" | |
end | |
backup_name | |
dump | |
get "#{backup_file}.bz2", "/tmp/#{application}.sql.bz2" | |
local_backup_name | |
local_dump | |
import_dump | |
end | |
desc "Pushes the database on to staging - be very sure that you want to do this on production!" | |
task :deploy_db do | |
backup_name | |
dump | |
local_backup_name | |
local_dump | |
upload("#{local_backup_file}.bz2", "#{shared_path}/#{dump_directory}/#{local_dbname}-from-local.bz2", :mode => 0666) | |
begin | |
run "cd #{shared_path}/#{dump_directory}/; bzcat #{local_dbname}-from-local.bz2 | mysql -u #{dbuser} -p #{dbname}", options={ :shell => false} do |ch, stream, out| | |
logger.info "[#{stream}] #{out}" | |
ch.send_data "#{dbpass}\n" if out=~ /^Enter password:/ | |
end | |
rescue Exception => error | |
puts "something broke: #{error}" | |
end | |
end | |
end | |
namespace :uploads do | |
desc "Mirrors the remote uploads directory with your local copy, doesn't download symlinks" | |
task :to_local do | |
run_locally("rsync -rtzvPO --rsh=ssh --progress #{user}@#{domain}:#{shared_path}/#{path_to_uploads_dir}/ #{path_to_uploads_dir}/") | |
end | |
end | |
namespace :cache do | |
desc "Clear Asset caches" | |
task :clear_assets, :roles => :app do | |
run "if [ -e #{current_release}/#{path_to_assets_dir}/cache ]; then rm -r #{current_release}/#{path_to_assets_dir}/cache/*; fi" | |
end | |
end | |
def time_string | |
Time.now.strftime("%Y-%m-%d-%H-%M-%S") | |
end | |
def delete_files(*args) | |
run "rm -f #{args.join(' ')}" | |
end | |
def delete_directories(*args) | |
run "rm -rf #{args.join(' ')}" | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment