Managing Mongrels on FreeBSD

Posted by Kevin Way Mon, 12 Feb 2007 15:00:00 GMT

Like a lot of other consultancies, we’re excited about Ruby on Rails. It provides a very nice framework to write clean, well-tested code in a great language. But hosting a production rails site isn’t quite as simple.

We run a fairly standard mix:
  • At the bottom, we have our Ruby on Rails websites.
  • They get web-enabled via Mongrel Cluster.
  • And then Apache 2.2 with mod_proxy_balancer spreads the end-users hits across the hordes of mongrels.

It works well, but there are a few problems with management. Notably, there is no FreeBSD rc.d script to easily start and stop individual sites, or to automatically start them all on boot.

As such, we quickly wrote a mongrel_cluster rc.d script that accepts a few rc.conf variables, to get your mongrel cluster running on FreeBSD in no time flat.

Configuration is simple.
  • Make a directory (/usr/local/etc/mongrel_cluster)
  • Put your mongrel_cluster yml files in that directory, naming each one for the site it represents (foo.yml bar.yml baz.yml)
Then edit your rc.conf and add the following
  • mongrel_cluster_enable=”YES”
  • mongrel_cluster_dir=”/usr/local/etc/mongrel_cluster”
  • mongrel_cluster_list=”foo bar baz”

And now put the attached mongrel_cluster file in your /usr/local/etc/rc.d directory.

Now you can do things like:

/usr/local/etc/rc.d/mongrel_cluster start to start all of your mongrel clusters at once. /usr/local/etc/rc.d/mongrel_cluster stop somesite to stop “somesite” while leaving the others running.

Hopefully that makes managing your FreeBSD mongrels just a bit simpler!

mongrel_cluster

Or see the whole file here:

#!/bin/sh
# PROVIDE: mongrel_cluster
# REQUIRE: DAEMON
# KEYWORD: shutdown
#
# Add the following line to /etc/rc.conf to enable mongrel_cluster:
# mongrel_cluster_enable (bool):      Set to "NO" by default.
#                                     Set it to "YES" to enable mongrel_cluster
# mongrel_cluster_list (str):         Set to "" by default.
#                                     The list of mongrel_cluster_list to start (leave off the .yml)
# mongrel_cluster_dir (str):          Set to "/usr/local/etc/mongrel_clusters" by default.
#
. /etc/rc.subr
PATH=$PATH:/usr/local/bin

name="mongrel_cluster" 
rcvar=`set_rcvar`
start_cmd="${name}_start" 
stop_cmd="${name}_stop" 

load_rc_config $name

eval "${rcvar}=\${${rcvar}:-'NO'}" 
[ -z "$mongrel_cluster_list" ]        && mongrel_cluster_list="" 
[ -z "$mongrel_cluster_dir" ]        && mongrel_cluster_dir="/usr/local/etc/mongrel_clusters" 
required_dirs=$mongrel_cluster_dir

# First, let's setup our start/stop routines
mongrel_cluster_start()
{
    echo "Starting Mongrel Clusters:" 
    for mongrel in $mongrel_cluster_list; do
        echo -n "   ${mongrel} -- " 
        /usr/local/bin/mongrel_rails cluster::start -C $mongrel_cluster_dir/$mongrel.yml
    done
    return 0
}

mongrel_cluster_stop()
{
    echo "Stopping Mongrel Clusters:" 
    for mongrel in $mongrel_cluster_list; do
        echo -n "   $mongrel -- " 
        /usr/local/bin/mongrel_rails cluster::stop -C $mongrel_cluster_dir/$mongrel.yml
    done
    return 0
}

# everything after the start/stop is a mongrel to be started/stopped
cmd="$1" 
if [ $# -gt 0 ]; then
    shift
fi
if [ -n "$*" ]; then
    mongrel_cluster_list="$*" 
fi

run_rc_command "${cmd}"