rubylinuxmongodbgod

Loading God scripts on startup - requires global gems?


I use God to watch over my Ruby APIs and services. I have created Init scripts to start up these services when the server boots. Doing this has led me to a couple of questions.

Firstly I have to have the scripts running as root? I found that as it loads with init.d scripts that the processes will then be managed by root - requiring Sudo for any changes.

Secondly, I have created RVM wrappers for some of the main processes (such as thin) which work brilliantly. But have found that some of the gems I use such as the Mongo gem will not get loaded from the context of the bundler (I assume that this is due to how the script is loaded and that it is loaded as root?) So I am forced to do a Gem install Mongo (and bson)

Is there a way to get init.d loaded scripts to load in the context of the bundler?

I might be doing this completely wrong as I am still fairly new to Ruby deployment and Linux configurations.

Here is an example of my god script:

require 'yaml'

config_path = '/opt/broker/current/config/api_config.yml'
config = YAML.load_file config_path

God.watch do |w|
  w.name = 'Broker_API'
  pid_file = config[:pid_file_path]
  w.pid_file = pid_file

  w.behavior :clean_pid_file

  w.dir = config[:deployed_current_path]
  w.env = config[:deployed_current_path]

  port = config[:api_port]
  server_logs = config[:api_logs]
  config_ru = config[:api_config_file]

  w.start = 'bundle exec thin -l %s -P %s -d -D -R %s -p %s --threaded start' %[server_logs, pid_file, config_ru, port]
  w.stop = 'bundle exec thin -l %s -P %s -d -D -R %s -p %s --threaded stop' %[server_logs, pid_file, config_ru, port]
  w.restart = 'bundle exec thin -l %s -P %s -d -D -R %s -p %s --threaded restart' %[server_logs, pid_file, config_ru, port]
  w.log = config[:api_god_log]

  w.keepalive
end

and my init script:

#!/bin/sh

### BEGIN INIT INFO
# Provides: god
# Required-Start: $all
# Required-Stop: $all
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: God
### END INIT INFO

NAME=god
DESC=god
GOD_BIN=/home/username/.rvm/wrappers/Godrunner/god
GOD_CONFIG=/etc/god/god.conf
GOD_LOG=/var/log/god.log
GOD_PID=/var/run/god.pid

set -e

RETVAL=0

case "$1" in
  start)
    echo -n "Starting $DESC: "
    $GOD_BIN load -c $GOD_CONFIG
 exit 0
fi

RETVAL=0

case "$1" in
  start)
    echo -n "Starting $DESC: "
    $GOD_BIN load -c $GOD_CONFIG
    RETVAL=$?
    echo "$NAME."
    ;;
  status)
 $GOD_BIN status
    RETVAL=$?
    ;;
  *)
    echo "Usage: god {start|status}"
    exit 1
    ;;
esac

exit $RETVAL

Solution

  • I have solved it this way:

    daemon --user $USER "$GOD_BIN \
    -c $CONFIG_FILE \
    -l $LOG_FILE \
    --log-level $LOG_LEVEL \
    -P $PID_FILE >/dev/null"
    

    This is the part which should replace your $GOD_BIN load -c $GOD_CONFIG. And now God runs as $USER.

    Now if you want it to know where your ruby and gems are you will have to provide it with this information. I am doing

    source /etc/profile.d/ruby.sh
    

    somewhere in the beginning of the script.

    ruby.sh contents:

    export PATH=/opt/ruby-2.1/bin/:$PATH
    export GEM_PATH=/opt/ruby-2.1/lib64/ruby/gems/2.1.0