Daemonizing Mongrel

is the current darling of the Ruby on Rails world, and for a very good reason – it is an excellent server for your Rails applications. Recently I switched to using Mongrel behind Apache running mod_proxy and I’ve had no complaints with it.

Before anyone points it out, yes there were some issues with this server recently but they were caused by mod_mono hogging all the memory, and not Mongrel/Rails. Once I disabled Mono normality was restored.

I did have one minor niggle though. After restarting my server a couple of times during the aforementioned Mono problems I had to restart Mongrel manually. I knew there was a better way to do it, but I didn’t know how. Now I do…

Here is a simple wrapper script to make any Rails app into a daemon (or service) with Mongrel:

!/bin/bash -e

. /lib/lsb/init-functions
MONGREL=/usr/bin/mongrel_rails
PORT=3000
ENVIRONMENT=production
APPNAME=rails_app
APPDIR=/path/to/your/app
case "$1" in
  start)
    log_begin_msg "Starting mongrel application: $APPNAME"
    $MONGREL start -c $APPDIR -e $ENVIRONMENT -p $PORT -d
    ;;
  stop)
    log_begin_msg "Stopping mongrel application: $APPNAME"
    $MONGREL stop -c $APPDIR
    ;;
  restart)
    log_begin_msg "Restarting mongrel application: $APPNAME"
    $MONGREL restart -c $APPDIR
    ;;
  reload|force-reload)
    ;;
esac
exit 0

Change `PORT`, `ENVIRONMENT`, `APPNAME` and `APPDIR` to suit and save it in your home folder (or somewhere else).

For the rest of this post assume you’ve changed nothing and saved it as `rails_app` in your home folder. In addition, the rest of the post is written from an Ubuntu perspective, so gratuitous use of `sudo` can be expected.

First we make it executable:

$ chmod +x rails_app

Then we copy it to `/etc/init.d/`:

$ sudo cp rails_app /etc/init.d/

Now we turn it into a system service:

$ sudo /usr/sbin/update-rc.d rails_app defaults

…and we’re done. When you reboot the service will start automatically, and you can start, stop and restart with:

$ sudo /etc/init.d/rails_app start
$ sudo /etc/init.d/rails_app stop
$ sudo /etc/init.d/rails_app restart

You can have as many of these as you like, but make sure you bind them to different ports. If you want to do something similar with Mongrel clusters, look here.


About this entry