Old Guy New Trick

An old guys journey to learn how to code.

Ooopsie, Time to Automate


Author: John on May 30, 2016

A week or so ago Digital Ocean had done some maintenance and had to restart my droplet.  Althought they had done their part and notified me about the outage, it slipped my mind.  It wasn't until I was trying to show someone my blog site that I noticed there was a problem.  As we landed on the home page for ognt.io I was presented with the "We're sorry, but something went wrong.  If you are the application owner check the logs for more information".

Then it hit me.  "Oh, yeah, I got an email about some server work."  At that point I realized, I need a better way to manage my Rails application for my OGNT web site.  I need for the application to start automatically on a server reboot.

So I found another great guide by the folks at Digital Ocean.  Following this guide, I started at the section: 'Create Unicorn Init Script'.  I had already installed and configured both Nginx and Unicorn, so I just needed the information on how to create a /etc/init.d/unicorn_appname file.

Here is the example/template file as found in the Digital Ocean guide I mentioned above:

#!/bin/sh

### BEGIN INIT INFO
# Provides:          unicorn
# Required-Start:    $all
# Required-Stop:     $all
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: starts the unicorn app server
# Description:       starts unicorn using start-stop-daemon
### END INIT INFO

set -e

USAGE="Usage: $0 "

# app settings
USER="deploy"
APP_NAME="appname"
APP_ROOT="/home/$USER/$APP_NAME"
ENV="production"

# environment settings
PATH="/home/$USER/.rbenv/shims:/home/$USER/.rbenv/bin:$PATH"
CMD="cd $APP_ROOT && bundle exec unicorn -c config/unicorn.rb -E $ENV -D"
PID="$APP_ROOT/shared/pids/unicorn.pid"
OLD_PID="$PID.oldbin"

# make sure the app exists
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 in
  start)
    sig 0 && echo >&2 "Already running" && exit 0
    echo "Starting $APP_NAME"
    su - $USER -c "$CMD"
    ;;
  stop)
    echo "Stopping $APP_NAME"
    sig QUIT && exit 0
    echo >&2 "Not running"
    ;;
  force-stop)
    echo "Force stopping $APP_NAME"
    sig TERM && exit 0
    echo >&2 "Not running"
    ;;
  restart|reload|upgrade)
    sig USR2 && echo "reloaded $APP_NAME" && exit 0
    echo >&2 "Couldn't reload, starting '$CMD' instead"
    $CMD
    ;;
  rotate)
    sig USR1 && echo rotated logs OK && exit 0
    echo >&2 "Couldn't rotate logs" && exit 1
    ;;
  *)
    echo >&2 $USAGE
    exit 1
    ;;
esac

After creating my /etc/init.d/unicorn_app-name-here file and trying to start unicorn, I got the following error:

➜  ~ sudo service unicorn_ognt start
Starting ognt
/home/jfhogarty/.rvm/gems/ruby-2.2.2/gems/bundler-1.10.6/lib/bundler/rubygems_integration.rb:292:in `block in replace_gem': unicorn is not part of the bundle. Add it to Gemfile. (Gem::LoadError)
  from /home/jfhogarty/.rvm/gems/ruby-2.2.2/bin/unicorn:22:in `<main>'
  from /home/jfhogarty/.rvm/gems/ruby-2.2.2/bin/ruby_executable_hooks:15:in `eval'
  from /home/jfhogarty/.rvm/gems/ruby-2.2.2/bin/ruby_executable_hooks:15:in `<main>'
➜  ~


Thankfully this was an easy issue to fix.  All I needed to do was to update my Rails applications Gemfile to include the following:
 

gem 'unicorn'

I had previously installed the unicorn gem outside of my Rails project so when I would start my app manually, it worked fine.  But for this automated solution, I needed to add the unicorn gem setting to my Gemfile.

Learn Something New Everyday

Last Edited by: John on June 01, 2016