Running Unicorn as a Service on Debian Linux

Unicorn is a very fast app server for Ruby on Rails. You just have to go to the APP_ROOT and type in “unicorn_rails”. And your app is running.

The problem with that is, if your server reboots your app is down. And you have to start it again by hand. That is not so cool!

Wouldn’t it be cool if you could start your Ruby on Rails like that:

/etc/init.d/unicorn start

and stop it like that:

/etc/init.d/unicorn stop

like all other services on Linux? And after a reboot unicorn starts automatically.

That is possible. Just use this script here for starting and stopping unicorn.

#!/bin/bash

### BEGIN INIT INFO
# Provides: unicorn
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start daemon at boot time
# Description: Enable service provided by daemon.
### END INIT INFO

PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
BUNDLE=/usr/local/bin/bundle
UNICORN=/usr/local/bin/unicorn_rails
KILL=/bin/kill
APP_ROOT=/var/www/my_app/current
PID=$APP_ROOT/pids/unicorn.pid
OLD_PID=$APP_ROOT/pids/unicorn.pid.oldbin
CONF=$APP_ROOT/unicorn.conf.rb
GEM_HOME=/var/www/my_app/shared/bundle/ruby/2.1.0/gems/

sig () {
  test -s "$PID" && kill -$1 `cat $PID`
}

case "$1" in
  start)
    echo "Starting unicorn rails app ..."
    cd $APP_ROOT
    if [ $USER == "ubuntu" ]
    then
      $BUNDLE exec unicorn_rails -D -c $CONF
    else
      su ubuntu -c "$BUNDLE exec unicorn_rails -D -c $CONF"
    fi
    echo "Unicorn rails app started!"
    ;;
  stop)
    echo "Stoping unicorn rails app ..."
    sig QUIT && exit 0
    echo "Not running"
    ;;
  restart)
    if [ -f $PID ];
    then
      echo "Unicorn PID $PID exists"
      /bin/kill -s USR2 `/bin/cat $PID`
      sleep 30
      echo "Old PID $OLD_PID"
      /bin/kill -9 `/bin/cat $OLD_PID`
    else
      echo "Unicorn rails app is not running. Lets start it up!"
      $0 start
    fi
    ;;
  status)
    ;;
  *)
    echo "Usage: $0 {start|stop|restart|status}"
    ;;
esac

Just customize the paths to your server and place the script in “/etc/init.d”. And ensure that the script is executable.

chmod ugo+x <YOUR_SCRIPT>

Than navigate to the direcotry “/etc/init.d” and execute this here:

update-rc.d <YOUR_SCRIPT> defaults

That will add your script to the default runlevels. So that your script will be executed by every reboot.