Last active
December 21, 2015 16:49
-
-
Save andreaseger/6336096 to your computer and use it in GitHub Desktop.
rails deploy w/ rvm, bundler, unicorn
This file contains hidden or 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
# Automatically precompile assets | |
load "deploy/assets" | |
# Execute "bundle install" after deploy, but only when really needed | |
require "bundler/capistrano" | |
# Application name | |
set :application, "page" | |
# Application environment | |
set :rails_env, :production | |
# Deploy username and sudo username | |
set :user, "deployer" | |
set :user_rails, "rails" | |
# App Domain | |
set :domain, "example.com" | |
# We don't want to use sudo (root) - for security reasons | |
set :use_sudo, false | |
# Target ruby version | |
set :rvm_ruby_string, 'ruby-2.0.0-p195-turbo@gemset' | |
# System-wide RVM installation | |
set :rvm_type, :system | |
# We use sudo (root) for system-wide RVM installation | |
set :rvm_install_with_sudo, true | |
# RVM integration | |
require "rvm/capistrano" | |
# git is our SCM | |
set :scm, :git | |
# Use github repository | |
set :repository, "[email protected]:sch1zo/repo.git" | |
# master is our default git branch | |
set :branch, "master" | |
# Deploy via github | |
set :deploy_via, :remote_cache | |
set :deploy_to, "/srv/http/#{application}" | |
# We have all components of the app on the same server | |
server domain, :app, :web, :db, :primary => true | |
# Install RVM and Ruby before deploy | |
before "deploy:setup", "rvm:install_rvm" | |
before "deploy:setup", "rvm:install_ruby" | |
# Apply default RVM version for the current account | |
after "deploy:setup", "deploy:set_rvm_version" | |
# copy settings | |
before "deploy:update_code", "deploy:copy_settings" | |
before "deploy:assets:precompile", "deploy:fix_symlinks" | |
# Fix log/ and pids/ permissions | |
after "deploy:setup", "deploy:fix_setup_permissions" | |
# Fix permissions | |
before "deploy:start", "deploy:fix_permissions" | |
after "deploy:restart", "deploy:fix_permissions" | |
after "deploy:assets:precompile", "deploy:fix_permissions" | |
# Clean-up old releases | |
after "deploy:restart", "deploy:cleanup" | |
# Unicorn config | |
set :unicorn_config, "#{current_path}/config/unicorn.rb" | |
set :unicorn_binary, "bash -c 'source /etc/profile.d/rvm.sh && cd #{current_path} && bundle exec unicorn_rails -c #{unicorn_config} -E #{rails_env} -D'" | |
set :unicorn_pid, "#{current_path}/tmp/pids/unicorn.pid" | |
set :su_rails, "sudo -u #{user_rails}" | |
namespace :deploy do | |
task :start, :roles => :app, :except => { :no_release => true } do | |
# Start unicorn server using sudo (rails) | |
run "#{su_rails} #{unicorn_binary}" | |
end | |
task :stop, :roles => :app, :except => { :no_release => true } do | |
run "if [ -f #{unicorn_pid} ]; then #{su_rails} kill `cat #{unicorn_pid}`; fi" | |
end | |
task :graceful_stop, :roles => :app, :except => { :no_release => true } do | |
run "if [ -f #{unicorn_pid} ]; then #{su_rails} kill -s QUIT `cat #{unicorn_pid}`; fi" | |
end | |
task :reload, :roles => :app, :except => { :no_release => true } do | |
run "if [ -f #{unicorn_pid} ]; then #{su_rails} kill -s USR2 `cat #{unicorn_pid}`; fi" | |
end | |
task :restart, :roles => :app, :except => { :no_release => true } do | |
stop | |
start | |
end | |
task :set_rvm_version, :roles => :app, :except => { :no_release => true } do | |
run "source /etc/profile.d/rvm.sh && rvm use #{rvm_ruby_string} --default" | |
end | |
task :fix_setup_permissions, :roles => :app, :except => { :no_release => true } do | |
run "#{sudo} chgrp #{user_rails} #{shared_path}/log" | |
run "#{sudo} chgrp #{user_rails} #{shared_path}/pids" | |
end | |
task :fix_permissions, :roles => :app, :except => { :no_release => true } do | |
# To prevent access errors while moving/deleting | |
run "#{sudo} chmod 775 #{current_path}/log" | |
run "#{sudo} find #{current_path}/log/ -type f -exec chmod 664 {} \\;" | |
run "#{sudo} find #{current_path}/log/ -exec chown #{user}:#{user_rails} {} \\;" | |
run "#{sudo} find #{current_path}/tmp/ -type f -exec chmod 664 {} \\;" | |
run "#{sudo} find #{current_path}/tmp/ -type d -exec chmod 775 {} \\;" | |
run "#{sudo} find #{current_path}/tmp/ -exec chown #{user}:#{user_rails} {} \\;" | |
run "#{sudo} chgrp #{user_rails} #{shared_path}/uploads -R" | |
end | |
task :copy_settings, :roles => :app, :except => { :no_release => true } do | |
%w(database.yml settings.yml newrelic.yml unicorn.rb).each do |file| | |
top.upload "config/#{file}", "#{shared_path}/#{file}" | |
end | |
end | |
task :fix_symlinks, :roles => :app, :except => { :no_release => true } do | |
run "#{sudo} ln -nfs #{shared_path}/uploads #{current_path}/public/u" | |
run "#{sudo} ln -nfs #{shared_path}/log #{current_path}/log" | |
run "#{sudo} chown -h #{user}:#{user_rails} #{current_path}/log" | |
run "#{sudo} chown -h #{user}:#{user_rails} #{current_path}/public/u" | |
%w(database.yml settings.yml newrelic.yml unicorn.rb).each do |file| | |
run "#{sudo} ln -nfs #{shared_path}/#{file} #{release_path}/config/#{file}" | |
end | |
end | |
# Precompile assets only when needed | |
namespace :assets do | |
task :precompile, :roles => :web, :except => { :no_release => true } do | |
# If this is our first deploy - don't check for the previous version | |
if remote_file_exists?(current_path) | |
from = source.next_revision(current_revision) | |
if capture("cd #{latest_release} && #{source.local.log(from)} vendor/assets/ app/assets/ | wc -l").to_i > 0 | |
run %Q{cd #{latest_release} && #{rake} RAILS_ENV=#{rails_env} #{asset_env} assets:precompile} | |
else | |
logger.info "Skipping asset pre-compilation because there were no asset changes" | |
end | |
else | |
run %Q{cd #{latest_release} && #{rake} RAILS_ENV=#{rails_env} #{asset_env} assets:precompile} | |
end | |
end | |
end | |
end | |
task :refresh_sitemaps do | |
run "cd #{latest_release} && RAILS_ENV=#{rails_env} rake sitemap:refresh:no_ping" | |
run "#{sudo} chgrp #{user_rails} #{current_path}/public/sitemap.xml.gz" | |
run "#{sudo} chmod 775 #{current_path}/public/sitemap.xml.gz" | |
#run "#{sudo} chgrp #{user_rails} #{current_path}/public/sitemap_index.xml.gz" | |
#run "#{sudo} chmod 775 #{current_path}/public/sitemap_index.xml.gz" | |
end | |
#before ["deploy:start", "deploy:restart"] do | |
# refresh_sitemaps | |
#end | |
task :recreate_carrierwave do | |
run "cd #{latest_release} && RAILS_ENV=#{rails_env} rake carrierwave:recreate_all" | |
end | |
# Helper function | |
def remote_file_exists?(full_path) | |
'true' == capture("if [ -e #{full_path} ]; then echo 'true'; fi").strip | |
end |
This file contains hidden or 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
# 4 workers is enough for our app | |
worker_processes 4 | |
# App location | |
@app = "/srv/http/page/current" | |
# Listen on fs socket for better performance | |
listen "#{@app}/tmp/sockets/unicorn.sock", :backlog => 64 | |
# Nuke workers after 30 seconds instead of 60 seconds (the default) | |
timeout 30 | |
# App PID | |
pid "#{@app}/tmp/pids/unicorn.pid" | |
# By default, the Unicorn logger will write to stderr. | |
# Additionally, some applications/frameworks log to stderr or stdout, | |
# so prevent them from going to /dev/null when daemonized here: | |
stderr_path "#{@app}/log/unicorn.stderr.log" | |
stdout_path "#{@app}/log/unicorn.stdout.log" | |
# To save some memory and improve performance | |
preload_app true | |
GC.respond_to?(:copy_on_write_friendly=) and | |
GC.copy_on_write_friendly = true | |
# Force the bundler gemfile environment variable to | |
# reference the Сapistrano "current" symlink | |
before_exec do |_| | |
ENV["BUNDLE_GEMFILE"] = File.join(@app, 'Gemfile') | |
end | |
before_fork do |server, worker| | |
# the following is highly recomended for Rails + "preload_app true" | |
# as there's no need for the master process to hold a connection | |
defined?(ActiveRecord::Base) and | |
ActiveRecord::Base.connection.disconnect! | |
end | |
after_fork do |server, worker| | |
# the following is *required* for Rails + "preload_app true", | |
defined?(ActiveRecord::Base) and | |
ActiveRecord::Base.establish_connection | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment