Deploying Mongrel behind Apache 2.0
July 25th, 2006Most of the documentation and writings for mongrel require setting up mongrel with apache 2.2, so that you get the benefit of the mod_balanced_proxy module. However there are an awful lot of production machines out there running apache 2.0.
For small installations, it turns out that it can be quite sufficient to run a single mongrel daemon behind Apache 2.0 and plain old mod_proxy, all on one machine. No, you won’t get high concurrency, and you won’t be able to load balance across machines, but it’s an incredibly simple, stable setup that can have your rails app up and running without mucking around with upgrading your web server or installing foreign RPMs.
Here are the prerequisites:
- You have apache 2.0 already installed and running.
- If you’re on a shared host, you’ve been assigned a high-numbered port to use for mongrel to listen on (just file a support ticket requesting this).
- You’ve followed one of the other tutorials online to verify that you can get a single mongrel instance running (even by hand) for your rails application on your high-numbered port on the same machine as the apache server.
From here on out, let’s presume the following. Substitute appropriately in the examples:
- The website that you’re developing is example.com
- Your high-numbered port is 4000
Go ahead and start up mongrel in production mode on your server. If you’re doing it by hand, you’ll probably use a command like:
$ cd /var/www/domains/example.com/current/
$ mongrel_rails start -e production -p 4000
Now you should be able to visit http://example.com/4000, and see your rails application. If you get a rails application error, check your production rails log and the mongrel log to see what’s going wrong. Make sure you’ve set up your production database (and production stanza in database.yml) properly. You might also have trouble if the host in question has firewalled the high-numbered ports, and your browser is running on a different machine. In that case, you can use the command-line web client “curl” on the server itself to request the page:
$ curl http://localhost:4000/
It should spit out the HTML of example.com’s home page.
Once you’re sure that mongrel is running properly on port 4000, we’re ready to use apache to proxy requests back to it, so that you can access the site without the port number.
If you’re using virtual hosts, this is the stanza that you can use in your httpd.conf file:
<VirtualHost *:80>
ServerName example.com
ProxyPass / http://localhost:4000/
ProxyPassReverse / http://localhost:4000/
</VirtualHost>
This simply tells apache that for requests that are destinted for example.com, proxy them to port 4000 on the localhost, which is where mongrel is running.
After checking and reloading your apache configuration, your site should now be available on http://example.com/
Making It Stick
The site’s running, but if the server reboots, mongrel may not be set up to restart automatically, so nothing will be serving your rails site. You’ll probably want to create a startup script that starts your mongrel servers on boot. My startup script contains a line like this for each site:
mongrel_rails start -e production -d -a 127.0.0.1 --user mongrel --group mongrel -p 4000 -c /var/www/domains/mydomain.com/current
Some things above are worth mentioning:
- It would be nicer to use a mongrel config file to store this information, rather than specifying it all on the command line. Unfortunately, I couldn’t seem to get the config files to work — mongrel would always ignore them. I eventually retreated to command-line options again.
-a 127.0.0.1tells mongrel to only accept requests from localhost. We don’t need to allow outsiders to access port 4000.- (Extra credit) It’s a good idea to run your services under their own account for security reasons. Mongrel supports this via the –user and –group options. I created a “mongrel” user and group, and then make sure that that user can read but not write to the source files. You also can give the mongrel user ownership of the directories that it needs to write to (log and sessions), rather than making those directories world-writable.
- The -c option tells mongrel which directory to “cd” to before it starts, so this points to the rails application directory.
