public
Last active

Unicorn, RVM Wrapper, Init.d

  • Download Gist
README.md
Markdown

You have your Rails Apps with specific Gemsets in RVM.

The following commands creates a wrapped unicorn_rails bin. Be sure to replace the variables and that you have unicorn in your bundle.

rvmsudo rvm wrapper [RUBY VERSION]@[GEMSET] [GEMSET] unicorn_rails

Now you have a /usr/local/rvm/bin/[GEMSET]_unicorn_rails I will refer to [GEMSET]_unicorn_rails as [WRAPPED_NAME]

Create the other files now, especially /etc/init.d/unicorn_init

sudo update-rc.d unicorn_init defaults

gistfile1.sh
Shell
1 2 3 4 5 6 7
# This is the actual config for your app
# Save this to /etc/unicorn/<APPNAME>.conf
# My configs look like this:
 
RAILS_ROOT=/home/deployer/<APPNAME>/current/
RAILS_ENV=production
UNICORN=/usr/local/rvm/bin/<WRAPPED_NAME>
unicorn.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
# RAILS_ROOT/config/unicorn.rb
# Search for "# SET ME!" and replace these with your own settings!.
 
# Set environment to development unless something else is specified
env = ENV["RAILS_ENV"] || "development"
RAILS_ROOT = # SET ME!
 
if ENV['MY_RUBY_HOME'] && ENV['MY_RUBY_HOME'].include?('rvm')
begin
rvm_path = File.dirname(File.dirname(ENV['MY_RUBY_HOME']))
rvm_lib_path = File.join(rvm_path, 'lib')
$LOAD_PATH.unshift rvm_lib_path
require 'rvm'
RVM.use_from_path! RAILS_ROOT
rescue LoadError
raise "RVM ruby lib is currently unavailable."
end
end
 
ENV['BUNDLE_GEMFILE'] = File.expand_path('../Gemfile', File.dirname(__FILE__))
require 'bundler/setup'
 
pid "#{RAILS_ROOT}/tmp/pids/unicorn.pid"
 
# See http://unicorn.bogomips.org/Unicorn/Configurator.html for complete
# documentation.
worker_processes 10 # SET ME!
 
# listen on both a Unix domain socket and a TCP port,
# we use a shorter backlog for quicker failover when busy
listen "/tmp/APPNAME.sock", :backlog => 1024 # SET ME!
 
# Preload our app for more speed
preload_app true
 
GC.respond_to?(:copy_on_write_friendly=) and
GC.copy_on_write_friendly = true
 
# nuke workers after 30 seconds instead of 60 seconds (the default)
timeout 60
 
# Production specific settings
if env == "production"
# Help ensure your application will always spawn in the symlinked
# "current" directory that Capistrano sets up.
working_directory RAILS_ROOT
 
# feel free to point this anywhere accessible on the filesystem
user 'deployer', 'staff'
shared_path = # SET ME!
 
stderr_path "#{shared_path}/log/unicorn.stderr.log"
stdout_path "#{shared_path}/log/unicorn.stdout.log"
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
if defined?(ActiveRecord::Base)
ActiveRecord::Base.connection.disconnect!
end
 
# Before forking, kill the master process that belongs to the .oldbin PID.
# This enables 0 downtime deploys.
old_pid = "#{RAILS_ROOT}/tmp/pids/unicorn.pid.oldbin"
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
end
 
after_fork do |server, worker|
# the following is *required* for Rails + "preload_app true",
if defined?(ActiveRecord::Base)
ActiveRecord::Base.establish_connection
end
 
# 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
unicorn_init.sh
Shell
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
#!/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: Start the unicorns at boot
# Description: Enable at boot time.
### END INIT INFO
 
# This is /etc/init.d/unicorn_init (without .sh)
# init.d script for single or multiple unicorn installations. Expects at least one .conf
# file in /etc/unicorn
#
# Modified by http://github.com/killercup
# based on modified version by jay@gooby.org http://github.com/jaygooby
# which is based on http://gist.github.com/308216 by http://github.com/mguterl
#
## A sample /etc/unicorn/my_app.conf
##
## RAILS_ENV=production
## RAILS_ROOT=/var/apps/www/my_app/current
## UNICORN="/usr/local/rvm/bin/<WRAPPED_NAME>" #see rvm wrapper above
#
# This configures a unicorn master for your app at /var/apps/www/my_app/current running in
# production mode. It will read config/unicorn.rb for further set up.
#
# You should ensure different ports or sockets are set in each config/unicorn.rb if
# you are running more than one master concurrently.
#
# If you call this script without any config parameters, it will attempt to run the
# init command for all your unicorn configurations listed in /etc/unicorn/*.conf
#
# /etc/init.d/unicorn start # starts all unicorns
#
# If you specify a particular config, it will only operate on that one
#
# /etc/init.d/unicorn start my_app
 
set -e
set -u
 
sig () {
test -s "$PID" && kill -$1 `cat "$PID"`
}
 
oldsig () {
test -s "$OLD_PID" && kill -$1 `cat "$OLD_PID"`
}
 
cmd () {
 
case $1 in
start)
sig 0 && echo >&2 "Already running" && exit 0
$CMD
echo "Starting"
;;
stop)
sig QUIT && echo "Stopping" && exit 0
echo >&2 "Not running"
;;
force-stop)
sig TERM && echo "Forcing a stop" && exit 0
echo >&2 "Not running"
;;
restart|reload)
sig USR2 && sleep 5 && oldsig QUIT && echo "Killing old master" `cat $OLD_PID` && exit 0
echo >&2 "Couldn't reload, starting '$CMD' instead"
$CMD
;;
upgrade)
sig USR2 && echo Upgraded && exit 0
echo >&2 "Couldn't upgrade, starting '$CMD' instead"
$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
}
 
setup () {
 
echo "$RAILS_ROOT: "
cd $RAILS_ROOT || exit 1
export PID=$RAILS_ROOT/tmp/pids/unicorn.pid
export OLD_PID="$PID.oldbin"
export RAILS_ENV=production
 
CMD="$UNICORN -c ${RAILS_ROOT}config/unicorn.rb -D"
}
 
start_stop () {
 
# either run the start/stop/reload/etc command for every config under /etc/unicorn
# or just do it for a specific one
 
# $1 contains the start/stop/etc command
# $2 if it exists, should be the specific config we want to act on
if [ $2 ]; then
. /etc/unicorn/$2.conf
setup
cmd $1
else
for CONFIG in /etc/unicorn/*.conf; do
# import the variables
. $CONFIG
setup
 
# run the start/stop/etc command
cmd $1
done
fi
}
 
ARGS="$1 $2"
start_stop $ARGS

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.