Skip to content

Instantly share code, notes, and snippets.

@gomayonqui
Last active August 29, 2015 14:14
Show Gist options
  • Save gomayonqui/a420f7c125eb2a7f5dfd to your computer and use it in GitHub Desktop.
Save gomayonqui/a420f7c125eb2a7f5dfd to your computer and use it in GitHub Desktop.
Nginx + Unicorn + Capistrano configuration files
AWS_KEY=AWS_KEY_VALUE
AWS_SECRET=AWS_SECRET
CAPISTRANO_USER=server_user
CAPISTRANO_PRODUCTION_IP=123.123.123.123
CAPISTRANO_STAGING_IP=123.123.123.123
[email protected]:gomayonqui/damaslindas.git
CAPISTRANO_PORT=22
# /etc/nginx/sites-available/app-name
upstream app-name {
server unix:/tmp/unicorn.app-name.sock fail_timeout=0;
}
server {
listen 80 default deferred;
# server_name example.com;
root /home/deployer/app-name/current/public;
location ^~ /assets/ {
gzip_static on;
expires max;
add_header Cache-Control public;
}
try_files $uri/index.html $uri @unicorn;
location @unicorn {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://app-name;
}
error_page 500 502 503 504 /500.html;
client_max_body_size 4G;
keepalive_timeout 10;
}
production:
adapter: postgresql
encoding: unicode
pool: 5
username: pguser
password: pguser
database: app-name
# config valid only for current version of Capistrano
lock '3.3.5'
set :repo_url, ENV['CAPISTRANO_URL']
set :cap_user, ENV['CAPISTRANO_USER']
set :server_ip, ENV['CAPISTRANO_STAGING_IP']
set :connection, ["#{fetch(:cap_user)}@#{fetch(:server_ip)}"]
set :unicorn_service, 'unicorn'
# Default value for :scm is :git
set :scm, :git
set :format, :pretty
set :keep_releases, 5
set :ssh_options, { forward_agent: true, port: ENV['CAPISTRANO_PORT'] }
set :linked_files, %w(.env config/database.yml config/unicorn.rb)
namespace :deploy do
after :publishing, :restart
desc 'Restart application'
task :restart do
on roles(:app), in: :sequence, wait: 5 do
execute "service #{fetch(:unicorn_service)} restart"
end
end
end
# config/production.rb
set :application, 'damaslindas'
set :rails_env, 'production'
set :unicorn_service, 'unicorn'
set :server_ip, ENV['CAPISTRANO_PRODUCTION_IP']
role :app, fetch(:connection)
role :web, fetch(:connection)
role :db, fetch(:connection)
ask :branch, 'master'
set :deploy_to, "/home/#{fetch(:cap_user)}/#{fetch(:application)}"
server fetch(:server_ip), user: fetch(:cap_user), roles: %w{web app}
# config/staging.rb
set :application, 'damaslindas-staging'
set :rails_env, 'staging'
set :unicorn_service, 'unicorn-staging'
set :server_ip, ENV['CAPISTRANO_STAGING_IP']
role :app, fetch(:connection)
role :web, fetch(:connection)
role :db, fetch(:connection)
ask :branch, `git symbolic-ref HEAD`.gsub(/^refs\/heads\//, '').chomp
set :deploy_to, "/home/#{fetch(:cap_user)}/#{fetch(:application)}"
server fetch(:server_ip), user: fetch(:cap_user), roles: %w{web app}
# /etc/init.d/unicorn
set -e
# Example init script, this can be used with nginx, too,
# since nginx and unicorn accept the same signals
# Feel free to change any of the following variables for your app:
TIMEOUT=${TIMEOUT-60}
USER=deployer
APP_NAME=app-name
ENVIRONMENT=production
APP_ROOT="/home/$USER/$APP_NAME/current"
PID="/home/$USER/$APP_NAME/shared/pids/unicorn.pid"
CMD="bundle exec unicorn -c $APP_ROOT/config/unicorn.rb -E $ENVIRONMENT -D"
action="$1"
DESC="Unicorn app for $APP_NAME"
set -u
old_pid="$PID.oldbin"
cd $APP_ROOT || exit 1
sig () {
test -s "$PID" && kill -$1 `cat $PID`
}
oldsig () {
test -s $old_pid && kill -$1 `cat $old_pid`
}
case $action in
start)
echo "Starting $DESC"
sig 0 && echo >&2 "Already running" && exit 0
$CMD
;;
stop)
echo "Stopping $DESC"
sig QUIT && exit 0
echo >&2 "Not running"
;;
force-stop)
sig TERM && exit 0
echo >&2 "Not running"
;;
restart|reload)
echo "Restarting $DESC"
sig HUP && echo reloaded OK && exit 0
echo >&2 "Couldn't reload, starting '$CMD' instead"
$CMD
;;
upgrade)
if sig USR2 && sleep 2 && sig 0 && oldsig QUIT
then
n=$TIMEOUT
while test -s $old_pid && test $n -ge 0
do
printf '.' && sleep 1 && n=$(( $n - 1 ))
done
echo
if test $n -lt 0 && test -s $old_pid
then
echo >&2 "$old_pid still exists after $TIMEOUT seconds"
exit 1
fi
exit 0
fi
echo >&2 "Couldn't upgrade, starting '$CMD' instead"
$CMD
;;
reopen-logs)
sig USR1
;;
*)
echo >&2 "Usage: $0 <start|stop|restart|upgrade|force-stop|reopen-logs>"
exit 1
;;
esac
# /home/deployer/app-name/current/config/unicorn.rb
# Sample verbose configuration file for Unicorn (not Rack)
#
# This configuration file documents many features of Unicorn
# that may not be needed for some applications. See
# http://unicorn.bogomips.org/examples/unicorn.conf.minimal.rb
# for a much simpler configuration file.
#
# See http://unicorn.bogomips.org/Unicorn/Configurator.html for complete
# documentation.
# Use at least one worker per core if you're on a dedicated server,
# more will usually help for _short_ waits on databases/caches.
worker_processes 2
# Since Unicorn is never exposed to outside clients, it does not need to
# run on the standard HTTP port (80), there is no reason to start Unicorn
# as root unless it's from system init scripts.
# If running the master process as root and the workers as an unprivileged
# user, do this to switch euid/egid in the workers (also chowns logs):
# user "unprivileged_user", "unprivileged_group"
app_name = "app-name"
deploy_to = "/home/deployer/#{app_name}"
rails_root = "#{deploy_to}/current"
socket_file = "/tmp/unicorn.#{app_name}.sock"
pid_file = "#{deploy_to}/shared/pids/unicorn.pid"
log_file = "#{rails_root}/log/unicorn.stdout.log"
error_log_file = "#{rails_root}/log/unicorn.stderr.log"
old_pid = pid_file + ".oldbin"
# Help ensure your application will always spawn in the symlinked
# "current" directory that Capistrano sets up.
working_directory rails_root
# listen on both a Unix domain socket and a TCP port,
# we use a shorter backlog for quicker failover when busy
listen socket_file, :backlog => 64
# nuke workers after 30 seconds instead of 60 seconds (the default)
timeout 30
# feel free to point this anywhere accessible on the filesystem
pid pid_file
# By default, the Unicorn logger will write to stderr.
# Additionally, ome applications/frameworks log to stderr or stdout,
# so prevent them from going to /dev/null when daemonized here:
stderr_path log_file
stdout_path error_log_file
# combine Ruby 2.0.0dev or REE with "preload_app true" for memory savings
# http://rubyenterpriseedition.com/faq.html#adapt_apps_for_cow
preload_app true
GC.respond_to?(:copy_on_write_friendly=) and
GC.copy_on_write_friendly = true
# Enable this flag to have unicorn test client connections by writing the
# beginning of the HTTP headers before calling the application. This
# prevents calling the application for connections that have disconnected
# while queued. This is only guaranteed to detect clients on the same
# host unicorn runs on, and unlikely to detect disconnects even on a
# fast LAN.
check_client_connection false
# local variable to guard against running a hook multiple times
run_once = true
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!
# Occasionally, it may be necessary to run non-idempotent code in the
# master before forking. Keep in mind the above disconnect! example
# is idempotent and does not need a guard.
if run_once
# do_something_once_here ...
run_once = false # prevent from firing again
end
# The following is only recommended for memory/DB-constrained
# installations. It is not needed if your system can house
# twice as many worker_processes as you have configured.
#
# # This allows a new master process to incrementally
# # phase out the old master process with SIGTTOU to avoid a
# # thundering herd (especially in the "preload_app false" case)
# # when doing a transparent upgrade. The last worker spawned
# # will then kill off the old master process with a SIGQUIT.
if File.exists?(old_pid) && server.pid != old_pid
begin
Process.kill("QUIT", File.read(old_pid).to_i)
rescue Errno::ENOENT, Errno::ESRCH
# someone else did our job for us
end
end
#
# Throttle the master from forking too quickly by sleeping. Due
# to the implementation of standard Unix signal handlers, this
# helps (but does not completely) prevent identical, repeated signals
# from being lost when the receiving process is busy.
# sleep 1
end
after_fork do |server, worker|
# per-process listener ports for debugging/admin/migrations
# addr = "127.0.0.1:#{9293 + worker.nr}"
# server.listen(addr, :tries => -1, :delay => 5, :tcp_nopush => true)
# the following is *required* for Rails + "preload_app true",
defined?(ActiveRecord::Base) and
ActiveRecord::Base.establish_connection
# if preload_app is true, then you may also want to check and
# restart any other shared sockets/descriptors such as Memcached,
# and Redis. TokyoCabinet file handles are safe to reuse
# between any number of forked children (assuming your kernel
# correctly implements pread()/pwrite() system calls)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment