Using monit to keep your rails app alive

Even the simplest rails applications are usually composed of several components — main application runs in a web server, connects to a database and has some way of running background tasks.

To keep your application alive you must make sure that each of this components is running and recover from errors.

Monit is the great tool for this purpose as it checks your services periodically and restarts them in case of any troubles. It has more advanced features like running a monitoring web server or sending emails, but we will focus on the basics.

Firstly, installation.

sudo apt-get monit

The configuration file is at /etc/monit/monitrc. We will use default settings, but we must specify which applications we want to check, so append these lines.

check process nginx with pidfile /var/run/nginx.pid
    start program = "/etc/init.d/nginx start"
    stop program = "/etc/init.d/nginx stop"

check process postgresql with pidfile /opt/postgres/data/postmaster.pid
    group database
    start program = "/etc/init.d/postgresql start"
    stop  program = "/etc/init.d/postgresql stop"

check process redis-server with pidfile /var/run/redis/redis-server.pid
    start program = "/etc/init.d/redis-server start"
    stop program = "/etc/init.d/redis-server stop"

check process sidekiq with pidfile /{project path}/tmp/pids/sidekiq.pid
  start program = "/bin/sh -c 'cd /{project path}; PATH=bin:/home/{user}/.rbenv/shims:/home/{user}/.rbenv/bin:$PATH nohup bundle exec sidekiq -e production -i 0 -P tmp/pids/sidekiq.pid >> log/sidekiq.log 2>&1 &'" as uid {user-id} and gid {user-gid} with timeout 90 seconds
  stop program = "/bin/sh -c 'cd /{project path}; PATH=bin:/home/{user}/.rbenv/shims:/home/{user}/.rbenv/bin:$PATH bundle exec sidekiqctl stop tmp/pids/sidekiq.pid'" as uid {user-id} and gid {user-gid} with timeout 90 seconds

Lines above are making sure that nginx, postgresql, redis and sidekiq are running. Sidekiq is a little bit trickier than the others as it has to be run through ruby (and rbenv in my case), so I’m executing a bash command under the user that the application is running under. You can get the user uid and gid by running the id command when logged under that user.

To reload the configuration you can run the following command.

sudo monit reload

From now on, monit is guarding your processes and your app is more robust.


Would you like to get the most interesting content about programming every Monday?
Sign up to Programming Digest and stay up to date!