Skip to content

Instantly share code, notes, and snippets.

@mlitwiniuk
Last active October 16, 2015 11:24
Show Gist options
  • Save mlitwiniuk/3e9d5f64da0e0280d9e3 to your computer and use it in GitHub Desktop.
Save mlitwiniuk/3e9d5f64da0e0280d9e3 to your computer and use it in GitHub Desktop.
Deploy stack
# Capfile
# Load DSL and set up stages
require 'capistrano/setup'
# Include default deployment tasks
require 'capistrano/deploy'
require 'capistrano/rails'
require 'capistrano/rbenv'
# Load custom tasks from `lib/capistrano/tasks` if you have any defined
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }
# config/deploy.rb
set :application, 'APP NAME'
set :repo_url, 'git@github.com:prograils/getwolfpack.git'
set :rbenv_type, :user # or :system, depends on your rbenv setup
set :rbenv_ruby, File.read('.ruby-version').strip
set :rbenv_prefix, "RBENV_ROOT=#{fetch(:rbenv_path)} RBENV_VERSION=#{fetch(:rbenv_ruby)} #{fetch(:rbenv_path)}/bin/rbenv exec"
set :rbenv_map_bins, %w{unicorn rake gem bundle ruby rails}
set :rbenv_roles, :all # default value
set :scm, :git
set :format, :pretty
set :linked_files, fetch(:linked_files, []).concat(%w(config/database.yml .env))
set :linked_dirs, fetch(:linked_dirs, []).concat(%w(log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system public/uploads))
set :keep_releases, 5
namespace :deploy do
after :finishing, 'deploy:cleanup'
after :publishing, 'deploy:restart'
end
# config/deploy/production.rb
set :stage, :production
set :deploy_to, '/home/prograilstutorial/wolfpackapp/'
set :branch, 'production'
# Simple Role Syntax
# ==================
# Supports bulk-adding hosts to roles, the primary
# server in each group is considered to be the first
# unless any hosts have the primary property set.
role :app, %w(prograilstutorial@testserver.prograils.com)
role :web, %w(prograilstutorial@testserver.prograils.com)
role :db, %w(prograilstutorial@testserver.prograils.com)
namespace :deploy do
desc 'Restart application'
task :restart do
on roles(:app), in: :sequence, wait: 5 do
execute :service, 'unicorn_wolfpackapp_production restart'
end
end
end
# config/unicorn.rb
app_dir = '/home/prograilstutorial/wolfpackapp/current'
shared_dir = '/home/prograilstutorial/wolfpackapp/shared'
worker_processes 2
working_directory app_dir
# Load app into the master before forking workers for super-fast
# worker spawn times
preload_app true
# nuke workers after 60 seconds (the default)
timeout 60
# listen on a Unix domain socket and/or a TCP port,
#listen 8080 # listen to port 8080 on all TCP interfaces
#listen "127.0.0.1:8080" # listen to port 8080 on the loopback interface
listen "#{shared_dir}/tmp/unicorn.socket"
pid "#{shared_dir}/tmp/pids/unicorn.pid"
stderr_path "#{shared_dir}/log/unicorn.stderr.log"
stdout_path "#{shared_dir}/log/unicorn.stdout.log"
# http://www.rubyenterpriseedition.com/faq.html#adapt_apps_for_cow
if GC.respond_to?(:copy_on_write_friendly=)
GC.copy_on_write_friendly = true
end
before_exec do |server|
ENV['BUNDLE_GEMFILE'] = "#{app_dir}/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!
##
# When sent a USR2, Unicorn will suffix its pidfile with .oldbin and
# immediately start loading up a new version of itself (loaded with a new
# version of our app). When this new Unicorn is completely loaded
# it will begin spawning workers. The first worker spawned will check to
# see if an .oldbin pidfile exists. If so, this means we've just booted up
# a new Unicorn and need to tell the old one that it can now die. To do so
# we send it a QUIT.
#
# Using this method we get 0 downtime deploys.
old_pid = "#{server.config[:pid]}.oldbin"
if File.exists?(old_pid) && server.pid != old_pid
begin
sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
Process.kill(sig, File.read(old_pid).to_i)
rescue Errno::ENOENT, Errno::ESRCH
# someone else did our job for us
end
end
end
after_fork do |server, worker|
# Unicorn master loads the app then forks off workers - because of the way
# Unix forking works, we need to make sure we aren't using any of the parent's
# sockets, e.g. db connection
defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection
# Redis and Memcached would go here but their connections are established
# on demand, so the master never opens a socket
end
#! /bin/bash
# /etc/init.d/unicorn_wolfpackapp_production
### BEGIN INIT INFO
# Provides: unicorn
# Required-Start: $local_fs $remote_fs $network $syslog
# Required-Stop: $local_fs $remote_fs $network $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: starts the unicorn web server
# Description: starts unicorn
### END INIT INFO
USER=prograilstutorial
APPDIR=wolfpackapp
STAGE=production
PATH=/home/$USER/.rbenv/bin:/home/$USER/.rbenv/shims:$PATH
DAEMON=unicorn
DAEMON_OPTS="-c /home/$USER/$APPDIR/current/config/unicorn-${STAGE}.rb -E $STAGE -D"
NAME=unicorn
DESC="Unicorn daemon for $USER / $APPDIR"
PID=/home/$USER/$APPDIR/shared/tmp/pids/unicorn.pid
case "$1" in
start)
CD_TO_APP_DIR="cd /home/$USER/$APPDIR/current"
START_DAEMON_PROCESS="bundle exec $DAEMON $DAEMON_OPTS"
echo -n "Starting $DESC: "
if [ `whoami` = root ]; then
su - $USER -c "$CD_TO_APP_DIR > /dev/null 2>&1 && $START_DAEMON_PROCESS"
else
$CD_TO_APP_DIR > /dev/null 2>&1 && $START_DAEMON_PROCESS
fi
echo "$NAME."
;;
stop)
echo -n "Stopping $DESC: "
kill -QUIT `cat $PID`
echo "$NAME."
;;
restart)
echo -n "Restarting $DESC: "
kill -USR2 `cat $PID`
echo "$NAME."
;;
reload)
echo -n "Reloading $DESC configuration: "
kill -HUP `cat $PID`
echo "$NAME."
;;
*)
echo "Usage: $NAME {start|stop|restart|reload}" >&2
exit 1
;;
esac
exit 0
# /etc/nginx/sites-enabled/wolfpackapp_site
upstream app-workers {
# fail_timeout=0 means we always retry an upstream even if it failed
# to return a good HTTP response (in case the Unicorn master nukes a single worker for timing out).
server unix:/home/prograilstutorial/wolfpackapp/shared/tmp/unicorn.socket fail_timeout=0;
}
server {
server_name getwolfpack.com;
root /home/prograilstutorial/wolfpackapp/current/public;
if ($http_transfer_encoding ~* chunked) {
return 444;
}
location / {
access_log off;
include proxy_params;
proxy_redirect off;
if (-f $request_filename) {
access_log off;
expires max;
break;
}
if (-f $request_filename.html) {
rewrite (.*) $1.html break;
}
if (!-f $request_filename) {
proxy_pass http://app-workers;
break;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment