Create a gist now

Instantly share code, notes, and snippets.

@Epigene /deploy.rb
Last active Feb 10, 2017

What would you like to do?
Mina deployment file for rails applications
# Mina Deploy
# ===========
#
# Adapted from Creative deploy stack in Manabalss v4, Mar.2015, updated to support staging on Jun.2015
# On first deploy do: mina setup --verbose
# Then do : mina deploy[initialize] --trace
#
# Usage examples:
# mina deploy[soft,seed,compile] to=staging # deploy task with all options | a simple `mina deploy` will deploy to production
# mina rake[db:seed] # for multi-argument tasks # mina 'rake[payments:refund[arg1\,arg2]]'
# mina oops # deletes the deploy.lock file in case a deployment messed up.
# mina boot # starts nginx and puma
# mina reboot # restarts nginx and puma
# mina puma_hard_reset # reset after major migrations or gem additions
# mina nginx_hard_reset # reset after nginx config changes
# mina shutdown # stops puma (for DB manipulation)
# mina rollback # symlinks current to the previous release folder and deletes last release, restarts puma
require 'mina/bundler'
require 'mina/rails'
require 'mina/git'
require 'mina/rvm' # Creative uses rvm
require 'mina/nginx'
set :term_mode, :system # Basic output, supports password prompt
# set :term_mode, :pretty # Does not support password input during deploy
set :bundle_binstubs, nil
set :ssh_options, '-A' # Needed for git sync to work, check droplet setup
def initialize_staging
set :rails_env, 'staging'
set :app_name, 'app'
set :domain, '1.2.3.4' # Droplet IP
set :user, 'deployer' # Username in the server to SSH to.
set :port, 22 # SSH port number.
set :deploy_to, "/home/deployer/apps/#{app_name}" # Creative deploys to "/home/deployer/apps/<appname>"
set :current, "#{deploy_to}/current"
set :pid_path, "/home/deployer/apps/#{app_name}/shared/tmp/pids/puma.pid"
# Configure git repo location
set :repository, 'git@github.com:Epigene/some_rails_app.git'
set :branch, 'staging'
puts "-----> Set up deployment variables for staging!"
end
def initialize_production
set :rails_env, 'production'
set :app_name, 'app'
set :domain, '1.2.3.5' # Droplet IP
set :user, 'deployer' # Username in the server to SSH to.
set :port, 22 # SSH port number.
set :deploy_to, "/home/deployer/apps/#{app_name}" # Creative deploys to "/home/deployer/apps/<appname>"
set :current, "#{deploy_to}/current"
set :pid_path, "/home/deployer/apps/#{app_name}/shared/tmp/pids/puma.pid"
# Configure git repo location
set :repository, 'git@github.com:Epigene/some_rails_app.git'
set :branch, 'master'
puts "-----> Set up deployment variables for production!"
end
case ENV['to']
when "production"
initialize_production
when "staging"
initialize_staging
else
initialize_production
end
# You must create these paths in `mina setup` | in shared/ (eg: shared/config/database.yml) in your server.
set :shared_paths, ['config/database.yml', 'log', 'public/system', 'tmp']
task :environment do
invoke :"rvm:use[ruby-2.2.3@app]" # Set App's ruby here
end
def heads_match?
`git fetch origin`
if `git diff #{branch} origin/#{branch} | head -4`.size < 1
return true
else
red "-----> Oops, your local #{branch} branch and origin differ.\n Commit and push your changes before deploying!"
return false
end
end
desc "Deploys the current version to the server."
task :deploy => :environment do |t, hash|
if heads_match?
deploy do
invoke :'git:clone'
invoke :'deploy:link_shared_paths'
invoke :'bundle:install'
if hash.extras.include?("migrate")
invoke :'force_migrate'
else
invoke :'rails:db_migrate'
end
invoke :"seed[#{hash.extras.include?("seed").to_s}]"
if hash.extras.include?("compile")
invoke :'rails:assets_precompile:force'
else
invoke :'rails:assets_precompile'
end
to :launch do
if hash.extras.include?("initialize")
puts "-----> Skipping server boot on init."
else
invoke :'update_crontab'
invoke :'nginx_link'
invoke :'run_resque'
if hash.extras.include?("soft")
invoke :'puma_reload'
else
invoke :'puma_hard_reset'
end
invoke :'deploy:cleanup'
end
end
end
else
# noop
end
end
desc "Deletes deploy.lock to allow redeploy"
task :oops => :environment do
queue! "cd #{deploy_to}"
queue! "rm deploy.lock"
end
desc "overrides mina's 'smart' migration and calls rake db:migrate explicitly"
task :force_migrate => :environment do
queue! %[cd #{current}]
queue! %[bundle exec rake db:migrate RAILS_ENV=#{rails_env}]
end
desc "Seed data to the database"
task :seed => :environment do |t, hash|
if hash.extras.include?("true")
puts "-----> Seeding!"
queue %[cd #{current}]
queue "bundle exec rake db:seed RAILS_ENV=#{rails_env}"
else
puts "-----> Seed absent, use 'mina deploy[seed]' if you need to seed\n"
end
end
desc "Hard-reboots puma and nginx"
task :reboot => :environment do
invoke :'nginx_hard_reset'
invoke :'puma_hard_reset'
end
desc "Turns ON both nginx and puma"
task :boot => :environment do
queue! %[cd #{current}]
queue! %[bundle exec pumactl start]
invoke :'nginx:start'
end
desc "Turns OFF both nginx and puma"
task :shutdown => :environment do
queue! %[cd #{current}]
queue! %[bundle exec pumactl -p $(cat #{pid_path}) stop]
invoke :'nginx:stop'
end
desc "Hard-resets puma"
task :puma_hard_reset => :environment do
queue! %[cd #{current}]
queue! %[(bundle exec pumactl -p $(cat #{pid_path}) stop && bundle exec pumactl start) || bundle exec pumactl start]
end
desc "Hard-resets nginx"
task :nginx_hard_reset => :environment do
queue! %[sudo service nginx stop]
queue! %[sudo service nginx start]
end
desc "Takes care of puma restart"
task :puma_reload => :environment do
queue! %[cd #{current}]
queue! %[bundle exec pumactl -p $(cat #{pid_path}) phased-restart || bundle exec pumactl start]
end
desc "Takes care of nginx conf"
task :nginx_link => :environment do
nginx_conf_path = "/home/deployer/apps/#{app_name}/current/config/deploy/#{rails_env}_nginx.conf"
queue! %[ln -nfs #{nginx_conf_path} /etc/nginx/sites-enabled/#{app_name}]
queue! %[ln -nfs #{nginx_conf_path} /etc/nginx/sites-available/#{app_name}]
end
desc "Updates crontab"
task :update_crontab => :environment do
queue! %[cd #{current} && bundle exec whenever --update-crontab #{app_name}]
end
desc "Runs resque"
task :run_resque => :environment do
queue! "cd #{current}"
queue! "bundle exec rake resque:restart_workers RAILS_ENV=#{rails_env}"
end
desc "Boots redis"
task :boot_redis => :environment do
queue! "sudo service redis_6392 start"
end
desc "Rolls back the latest release"
task :rollback => :environment do
queue! %[echo "-----> Rolling back to previous release for #{app_name}!"]
# Delete existing sym link and create a new symlink pointing to the previous release
queue %[echo -n "-----> Creating new symlink from the previous release: "]
queue %[ls "#{deploy_to}/releases" -Art | sort | tail -n 2 | head -n 1]
queue! %[ls -Art "#{deploy_to}/releases" | sort | tail -n 2 | head -n 1 | xargs -I active ln -nfs "#{deploy_to}/releases/active" "#{deploy_to}/current"]
# Remove latest release folder (active release)
queue %[echo -n "-----> Deleting active release: "]
queue %[ls "#{deploy_to}/releases" -Art | sort | tail -n 1]
queue! %[ls "#{deploy_to}/releases" -Art | sort | tail -n 1 | xargs -I active rm -rf "#{deploy_to}/releases/active"]
queue! %[cd #{current}]
queue! %[(bundle exec pumactl -p $(cat #{pid_path}) stop && bundle exec pumactl start) || bundle exec pumactl start]
end
# Put any custom mkdir's in here for when `mina setup` is ran.
# For Rails apps, we'll make some of the shared paths that are shared between
# all releases.
task :setup => :environment do
queue! %[mkdir -p "#{deploy_to}/shared/log"]
queue! %[chmod g+rx,u+rwx "#{deploy_to}/shared/log"]
queue! %[mkdir -p "#{deploy_to}/shared/config"]
queue! %[chmod g+rx,u+rwx "#{deploy_to}/shared/config"]
queue! %[mkdir -p "#{deploy_to}/shared/public"]
queue! %[chmod g+rx,u+rwx "#{deploy_to}/shared/public"]
queue! %[mkdir -p "#{deploy_to}/shared/public/system"]
queue! %[chmod g+rx,u+rwx "#{deploy_to}/shared/public/system"]
queue! %[mkdir -p "#{deploy_to}/shared/tmp/"]
queue! %[chmod g+rx,u+rwx "#{deploy_to}/shared/tmp/"]
queue! %[mkdir -p "#{deploy_to}/shared/tmp/pids"]
queue! %[chmod g+rx,u+rwx "#{deploy_to}/shared/tmp/pids"]
queue! %[touch "#{deploy_to}/shared/tmp/pids/puma.pid"]
queue! %[touch "#{deploy_to}/shared/config/database.yml"]
queue %[echo "-----> Be sure to edit 'shared/config/database.yml'."]
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment