Swiftiply combined with Merb is a pretty nice way to serve up your application. And while we hope that both are stable, it would be nice to know that just in case anything went wrong they would restart. It would also be nice for the application to automatically start upon reboot.
That is what we are going to attempt to setup using Monit.
Prerequisites:
We assume you already have Swiftiply and Merb setup and functioning properly. We are also assuming that you have Monit installed and functioning properly.
Versions:
- Ubuntu 7.10 (Gutsy)
- Ruby: 1.8.6
- Merb: 0.5.2
- Swiftiply: 0.6.1.1
- Monit 4.8.1
- Assumes your Merb app is "frozen" (rake merb:freeze)
Setup Monit To Auto-Start
> sudo vim /etc/default/monitThis is a pre-existing file. Edit as follows:startup=1Create init script for SwiftiplyThe big problem with trying to monitor Swiftiply was that it does not write a pidfile for Monit to track. Fortunately someone solved the problem, and Google found it. Big credit for the script: http://pastie.textmate.org/107044.txt
> sudo vim /etc/init.d/swiftiplyThis will be a new blank file. Edit as follows:#!/bin/bash
function generatepid(){
current_pid=`pgrep -f 'swiftiply -c /etc/swiftiply.conf'`
pidfile_pid=`cat /var/run/swiftiply.pid`
if [[ $current_pid = '' ]]; then
rm /var/run/swiftiply.pid
elif [[ $pidfile_pid != $current_pid ]]; then
echo $current_pid > /var/run/swiftiply.pid
fi
}
case "$1" in
start)
echo -n "Starting swiftiply:"
swiftiply -c /etc/swiftiply.conf
generatepid
echo
;;
stop)
echo -n "Stopping swiftiply:"
killall -9 swiftiply
generatepid
echo
;;
restart)
$0 stop
$0 start
;;
pid)
generatepid
;;
*)
echo "usage: $0 [start|stop|restart|pid]"
esac
exit 0I will use "app1" but you can replace that with whatever name you would like as an identifier for this specific Merb application.
> sudo vim /etc/init.d/merb_app1This will be a new blank file. Edit as follows:#!/bin/bash
case "$1" in
start)
echo -n "Starting Merb for App1:"
export SWIFT=1
export HOME="/home/admin" #Assuming you have a user admin
cd /full/path/to/your/app/current/
sudo ./script/merb -d -h 127.0.0.1 -p 30000 -e production
echo
;;
stop)
echo -n "Stopping Merb for App1:"
cd /full/path/to/your/app/current/
sudo ./script/stop_merb
echo
;;
restart)
$0 stop
$0 start
;;
*)
echo "usage: $0 [start|stop|restart]"
esac
exit 0The -p directive should point to the same port that you have configured Swiftiply to listen to for this specific app. Also, this is assuming that you have Merb frozen. If not, then you will need to change "./script/merb" and "./script/stop_merb" to their unfrozen counterparts.Set Permissions
Without these permissions set to execute the init scripts will not work.
> sudo chmod 755 /etc/init.d/swiftiply
> sudo chmod 755 /etc/init.d/merb_app1> sudo vim /etc/monit/monitrcAdd the following in to the pre-existing configuration: check process swiftiply with pidfile /var/run/swiftiply.pid
group root
start program = "/etc/init.d/swiftiply start"
stop program = "/etc/init.d/swiftiply stop"
if 5 restarts within 5 cycles then timeout
include /etc/monit/app1Configure App1 Monit FileYou could have just added the following in the main file, but I prefer to use the include statement and keep them in separate files.
> sudo vim /etc/monit/app1This will be a new blank file. Edit as follows: check process merb_app1
with pidfile /full/path/to/your/app/current/log/merb.30000.pid
start program = "/etc/init.d/merb_app1 start"
stop program = "/etc/init.d/merb_app1 stop"
if 5 restarts within 5 cycles then timeout
depends on swiftiply30000 should be replaced with the specific port that you have Swiftiply listening on for this application. The "depends on swiftiply" will make sure that swiftiply is started first.Does it work?
> sudo monit -t
> sudo /etc/init.d/monit force-reload
> sudo monit validate
> sudo monit summaryCaveatsThis setup only checks to make sure the processes are up and running.
2 comments:
Great article! However, I think the way you monitor Swiftiply is wrong. The problem is that if the Swiftiply process dies, the pid file will remain, which means that Monit won't be able to restart it.
The solution would be to add these 2 lines to your "check process monit" section:
if failed host 127.0.0.1 port 80 then restart
if failed host 127.0.0.1 port 30000 then restart
I haven't tested but it should work. Thoughts?
Thanks for leaving a comment.
Yeah, I agree with your thoughts. Haven't tried the port testing, but that might work better.
If you get a chance to test, please post your results back.
Post a Comment