Skip to content

Instantly share code, notes, and snippets.

@oferreiro
Last active January 1, 2016 11:09
Show Gist options
  • Save oferreiro/8136141 to your computer and use it in GitHub Desktop.
Save oferreiro/8136141 to your computer and use it in GitHub Desktop.
Debian style unicorn init.d
#!/bin/bash
# /etc/init.d/unicorn
# ### 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: unicorn service
# Description: This script will start unicorn installations
# specified in /etc/unicorn/*.conf
### END INIT INFO
# Modified by oseias at oferreiro.info on https://gist.github.com/oferreiro/8136141
# based on https://gist.github.com/jaygooby/504875
#
###########################################################
## A sample /etc/unicorn/my_app.conf
##
## RAILS_ENV=production
## RAILS_ROOT=/var/apps/www/my_app/current
## USERNAME=user
##
#
# This configures a unicorn master for your app at /var/apps/www/my_app/current running in
# production mode. It will read config/unicorn/production.rb for further set up.
#
# You should ensure different ports or sockets are set in each config/unicorn/${RAILS_ENV}.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 # starts only /etc/unicorn/my_app.conf
#
set -e
NAME="unicorn"
CONFIG_PATH=/etc/unicorn
ARGS="$1 $2"
TIMEOUT=30
if ! [[ -d ${CONFIG_PATH} ]]; then
echo "Config path ${CONFIG_PATH} does not exists."
exit 1
fi
get_pid () {
[[ -s "${PIDFILE}" ]] && cat "${PIDFILE}"
}
sig () {
[[ -s "${PIDFILE}" ]] && kill -$1 $(cat "${PIDFILE}")
}
oldsig () {
[[ -s "${OLD_PIDFILE}" ]] && kill -$1 $(cat "${OLD_PIDFILE}")
}
unicorn_cmd () {
CURR_USER=$(whoami)
UNICORN_CMD="bundle exec unicorn -c config/unicorn/${RAILS_ENV}.rb -E ${RAILS_ENV} -D"
if ! [[ ${USERNAME} ]] || [[ ${USERNAME} == ${CURR_USER} ]]; then
${UNICORN_CMD}
else
su -c "${UNICORN_CMD}" ${USERNAME}
fi
}
cmd () {
case $1 in
start)
sig 0 && echo >&2 "Already running" && return 1
echo "Starting"
unicorn_cmd
;;
stop)
sig QUIT && echo "Stopping" && return 0
echo >&2 "Not running" && return 1
;;
force-stop)
sig TERM && echo "Forcing a stop" && return 0
echo >&2 "Not running" && return 1
;;
restart|reload)
echo -n "Restarting "
sig HUP && echo "HUP signal sent" && return 0
echo >&2 "Couldn't reload, starting instead"
unicorn_cmd
;;
rotate)
sig USR1 && echo "Rotated logs OK" && return 0
echo >&2 "Couldn't rotate logs" && return 1
;;
upgrade)
echo -n "Upgrading"
OLD_PID=get_pid
if sig USR2; then
n=${TIMEOUT}
echo
echo -n "Waiting up new master"
while [[ $n -ge 0 ]]; do
if [[ -e "${PIDFILE}" ]] && [[ "${OLD_PID}" -ne "$(get_pid)" ]] ; then
break
fi
printf '.' && sleep 1 && n=$(( $n - 1 ))
done
n=${TIMEOUT}
echo
echo -n "Waiting down old master"
while [[ -s ${OLD_PIDFILE} ]] && [[ $n -ge 0 ]] ; do
printf '.' && sleep 1 && n=$(( $n - 1 ))
done
echo
if [[ -s ${OLD_PIDFILE} ]] && [[ $n -lt 0 ]]; then
echo >&2 "${OLD_PIDFILE} still exists after ${TIMEOUT} seconds"
oldsig QUIT
return 1
fi
if sig 0; then
return 0
fi
fi
echo >&2 "Couldn't upgrade, starting instead"
unicorn_cmd
;;
*)
echo >&2 "Usage: ${NAME} <start|stop|restart|upgrade|rotate|force-stop>"
exit 0
;;
esac
}
setup () {
cd ${RAILS_ROOT} && echo -n "Working in ${RAILS_ROOT}: " || exit 1
unset PIDFILE
unset OLD_PIDFILE
export PIDFILE="${RAILS_ROOT}/tmp/pids/unicorn.pid"
export OLD_PIDFILE="${PIDFILE}.oldbin"
}
main () {
# either run the start/stop/reload/etc command for every config under ${CONFIG_PATH}
# 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
CONF=${CONFIG_PATH}/$2.conf
if [[ -e ${CONF} ]]; then
. ${CONF} || exit 1
setup
cmd $1
else
echo "${NAME}: config file ${CONF} does not exists..."
exit 1
fi
else
CONFIGS=${CONFIG_PATH}/*.conf
for CONFIG in ${CONFIGS}; do
echo -n "Loading ${CONFIG}..."
if [[ -e ${CONFIG} ]]; then
# import variables
. ${CONFIG}
echo 'ok'
setup
cmd $1
else
echo
echo "${NAME}: no one config file in ${CONFIG_PATH}..."
exit 1
fi
done
fi
}
if [ $# -eq 0 ]
then
cmd
else
main ${ARGS}
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment