Skip to content

Instantly share code, notes, and snippets.

@cassioalmeidas
Forked from nebiros/Gemfile
Created March 1, 2016 18:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cassioalmeidas/988d3688d2009a619791 to your computer and use it in GitHub Desktop.
Save cassioalmeidas/988d3688d2009a619791 to your computer and use it in GitHub Desktop.
rails + unicorn + rbenv + init.d daemon
group :production do
gem "unicorn"
end
APP_DIR = File.expand_path("../../", __FILE__)
# This loads the application in the master process before forking
# worker processes
# Read more about it here:
# http://unicorn.bogomips.org/Unicorn/Configurator.html
preload_app true
worker_processes 4
working_directory APP_DIR
# This is where we specify the socket.
# We will point the upstream Nginx module to this socket later on
listen "#{APP_DIR}/tmp/sockets/unicorn.sock", :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
# user 'nginx', 'www-data'
pid "#{APP_DIR}/tmp/pids/unicorn.pid"
stderr_path "#{APP_DIR}/log/unicorn.stderr.log"
stdout_path "#{APP_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_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/sh
### BEGIN INIT INFO
# Provides: unicorn
# Required-Start: $all
# Required-Stop: $network $local_fs $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
# Change these to match your app:
USER=<USER_WITH_RBENV>
APP_NAME=<APPLICATION_NAME>
APP_PATH=<APPLICATION_PATH>
ENV=<ENVIRONMENT>
RBENV_RUBY_VERSION=<RBENV_RUBY_VERSION>
# env
APP_ROOT="$APP_PATH/$APP_NAME"
RBENV_ROOT="/home/$USER/.rbenv"
PATH="$RBENV_ROOT/bin:$RBENV_ROOT/shims:$PATH"
SET_PATH="cd $APP_ROOT; rbenv rehash; rbenv local $RBENV_RUBY_VERSION"
DAEMON="bundle exec unicorn_rails"
DAEMON_OPTS="-c $APP_ROOT/config/unicorn.rb -E $ENV -D"
CMD="$SET_PATH; $DAEMON $DAEMON_OPTS"
NAME=unicorn
DESC="Unicorn app for $APP_NAME"
PID="$APP_ROOT/tmp/pids/unicorn.pid"
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 ${1-help} in
start)
sig 0 && echo >&2 "Already running" && exit 0
su - $USER -c "$CMD"
;;
stop)
sig QUIT && exit 0
echo >&2 "Not running"
;;
force-stop)
sig TERM && exit 0
echo >&2 "Not running"
;;
restart|reload)
sig HUP && echo reloaded OK && exit 0
echo >&2 "Couldn't reload, starting '$CMD' instead"
su - $USER -c "$CMD"
;;
upgrade)
sig USR2 && exit 0
echo >&2 "Couldn't upgrade, starting '$CMD' instead"
su - $USER -c "$CMD"
;;
rotate)
sig USR1 && echo rotated logs OK && exit 0
echo >&2 "Couldn't rotate logs" && exit 1
;;
*)
echo >&2 "Usage: $0 <start|stop|restart|upgrade|rotate|force-stop>"
exit 1
;;
esac
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment