Proxying requests to a mongrel cluster is one of the ways of serving your Ruby on Rails web application.
Let's create a cluster of mongrels and configuring it to restart after a reboot.
This article will stand on it's own and is not strictly part of a series. However, the base setup for serving a Ruby on Rails application using mongrels and Apache is discussed here and the base for mongrels and Nginx can be found in this article.
Let's start by installing the mongrel cluster gem:
sudo gem install mongrel_cluster
I had rubygems v0.9.5 on my demo slice so the dependencies were automatically taken care of.
In all, the following gems were installed:
gem_plugin-0.2.3 cgi_multipart_eof_fix-2.5.0 daemons-1.0.9 fastthread-1.0.1 mongrel-1.1.1 mongrel_cluster-1.0.5
Before we configure the cluster, you will need to have a Ruby on Rails application. The basic structure created via the 'rails' command is more than sufficient:
cd /home/demo/public_html rails railsapp
Move into your rails application:
The command to create your application's cluster is as follows:
mongrel_rails cluster::configure -e production -p 8000 -N 2 -c /home/demo/public_html/railsapp -a 127.0.0.1
-e production: sets the environment. Change this to suit whether you are developing the application or serving the final product.
-p 8000 -N 2: sets the port to start the cluster on and then sets the number of mongrel instances. In this example I am following the vhost setup described in the Apache, rails and mongrels article. Set the port and number of mongrels to suit your application.
-c /home/demo/public_html/railsapp: sets the base directory of your rails application. It is important you use the full path to your rails folder.
-a 127.0.0.1: sets the address to bind to. For most applications the localhost port is sufficient.
As you can see, the separate options for the configure command are quite simple. To find out more enter:
mongrel_rails cluster::configure --help
So what did the command actually do? Well, it created a file called 'mongrel_cluster.yml' in the rails config directory. Let's take a look:
If you used the example above, the contents will be:
--- cwd: /home/demo/public_html/railsapp log_file: log/mongrel.log port: "8000" environment: production address: 127.0.0.1 pid_file: tmp/pids/mongrel.pid servers: 2
As you can see, the setting are from the configure command. There are also two entries that we did not specifically define: The log location and the pid_file. Feel free to adjust these paths to one of your choosing but both defaults are usually just fine.
Starting and Stopping
There are several ways of starting and stopping the mongrel_cluster.
Ensuring you are in the rails root folder issue this command:
Which will simply output:
starting port 8000 starting port 8001
And to stop or restart the cluster:
mongrel_rails cluster::stop .. mongrel_rails cluster::restart
That's all well and good but the cluster won't restart on a reboot. Not very handy.
You can read more about mongrel clusters on the main mongrel website but do be aware the instructions on the site do not work without all of the commands listed below.
Let's stop any running mongrels with a:
And then creating a folder in the 'etc' folder:
sudo mkdir /etc/mongrel_cluster
We need to link the mongrel_cluster.yml (which we just created) to the folder:
sudo ln -s /home/demo/public_html/railsapp/config/mongrel_cluster.yml /etc/mongrel_cluster/railsapp.yml
You will have to do that for each and every mongrel_cluster you create (if you want them to start automatically). So if you have two rails applications, you will have two symlinks.
Next, copy the gem init script to the init.d directory:
sudo cp /usr/lib/ruby/gems/1.8/gems/mongrel_cluster-1.0.5/resources/mongrel_cluster /etc/init.d/
Make it executable:
sudo chmod +x /etc/init.d/mongrel_cluster
Now we need to add the script to the runtime list:
sudo /usr/sbin/update-rc.d -f mongrel_cluster defaults
Finally, to ensure the script correctly initialises the cluster on a reboot, you must have this symlink in place:
sudo ln -s /usr/bin/ruby1.8 /usr/bin/ruby
If you take a look at the mongrel init script, you will see it tries to set the user and group of the cluster to 'mongrel'.
Problem is, we don't have a mongrel user or group.
We can do a few things here including changing the init script. The problem with that is if the mongel_cluster gem is updated then we will have to remember any changes we made when we link to the newer version.
Instead, a neat way is to simply create a mongrel user and then add it to the www-data group (thanks to Adam and Tad for this tip):
sudo useradd mongrel sudo usermod -a -G www-data mongrel
Just to clarify: when we set the permissions on the public_html folder, we ensured www-data had access to the folders. Now, the default mongrel_cluster user also has access to the correct folders.
Starting and Stopping v.2
Now we have the mongrel_cluster init script starting and all the permissions seem nicely sorted, let's have a very quick look at how we can start and stop the cluster from the command line.
You can use the command 'mongrel_cluster_ctl' to start, stop and restart your clusters. The advantage of this method is that you don't have to be in the rails directory to issue it.
Let's use this command to find the status of any clusters:
Checking all mongrel_clusters... mongrel_rails cluster::status -C railsapp.yml ... found pid_file: tmp/pids/mongrel.8000.pid found mongrel_rails: port 8000, pid 2065 found pid_file: tmp/pids/mongrel.8001.pid found mongrel_rails: port 8001, pid 2068
Good, I have just rebooted so expect to see the two mongrels running.
To start/stop/restart the cluster(s):
mongrel_cluster_ctl start ... mongrel_cluster_ctl stop ... mongrel_cluster_ctl restart
Remember you may need to put a sudo in front of the 'stop' command if you have just rebooted as the process started on reboot is owned by root.
Quite a lot going on in this article: We covered most areas needed to create, configure, start, stop and restart a mongrel_cluster along with creating an init script to restart the cluster(s) in a reboot.
Once you have gone through the commands a couple of times you will see how easy it is to setup and control your rails applications.