acts_as_pipe :web

Rails developers are beginning to find themselves lost in a sea of multiple deployment options. Mongrel is the up-and-coming deployment option for Rails, while FastCGI is quickly becoming the dinosaur. It seems likely that by the time Rails 1.2 rolls out, Mongrel will be the recommended way to deploy into production. To bring myself up to speed, I recently spent some time learning more about Mongrel, the latest and greatest way to get your Rails app running smoothly.
People who keep tabs on the latest in Rails development might already be aware that the web is a pipe (and apparently not a series of tubes). But since I have been using Rails for some time and am more familiar using lighttpd, mod_fastcgi, and Capistrano, I began wondering what all the fuss was about. What is Mongrel, why is he in a Pound, and what’s the problem with mod_proxy? If you have been following the Rails blog (1,2,3), you may already know some of the pieces. For me, an overview of the problem being solved was lacking.

First, I needed motivation to switch – “the why.” And the why is simple: speed. Mongrel and mod_proxy often have far better performance than a FastCGI setup (although this may depend from setup to setup, application to application). As better performance means less overhead, I was on board for learning what this was all about. Mongrel also has other advantages; most importantly, it is easier to debug problems (as discussed in the web-as-pipe essay). As I found out, it has only a marginal learning curve.

Mongrel is essentially a replacement for Webrick – it is a Ruby/C++ web server for Rails. Unlike Webrick, it is tuned for performance. Mongrel is a gem, so it is available by simply typing gem install mongrel at your command prompt. (Note that Mongrel also requires Ruby 1.8.4—1.8.2 will not work.) Once installed, go to your Rails root and type mongrel_rails start and you’re ready to start developing using Mongrel instead of Webrick.

You might be asking yourself: why would Mongrel be as fast or faster than a FastCGI setup? The key is that a FastCGI request is not very different from serving a web, or HTTP request. More details are in the web-as-pipe article, but the essentials are these: FastCGI simply rewrites the web request into a different language. By running a FastCGI server, you’re running a server that speaks a different language than the web, but in the end it has to do the same thing. Very little can be gained by serving a request to Rails over FastCGI instead of HTTP.

Since Mongrel is production-ready, we will also use it for our production environment. In production, the goal is to use a standard-issue web server to proxy requests to a cluster of a Mongrel processes.

Fortunately, Mongrel is ready to deliver with mongrel_cluster, allowing one to set up multiple Mongrel processes quickly and easily. The documentation is so good for this step that any further explanation would be redundant. My favorite feature is worth mentioning: the start-at-bootup script support. By creating an /etc/mongrel-cluster/ directory, all your Rails apps can be started automatically when your system reboots, as well as controlled through a convenient init.d script. This problem is rarely solved so elegantly. Bravo!

At this point, you have a number of options to proxy requests to Mongrel—a problem which has been well covered elsewhere. The most straightforward is to use lighttpd or Apache 2.2 to proxy requests directly to your Mongrel cluster. This relies on your web server to have a solid proxy implementation that will work for your infrastructure. If you prefer lighttpd, you may find that mod_proxy has some performance issues, although it works fine for smaller scale setups. While we wait for lighttpd’s mod_proxy_core to make its way into a final release, Pound can be used to work around lighttpd’s limitations. Alternately, you can use Apache 2.2 and mod_proxy_balancer.