Friday, August 3, 2007

Server Info

Time For A Grown-Up Server: Rails, Mongrel, Apache, Capistrano and You

More and more Rails developers are finding out that deploying a Rails application isn’t as simple as upload and rename; Rails apps work best when running all the time, and many Rails programmers are moving from traditional, shared hosts, like Dreamhost, to virtual private servers, like Rimuhosting, which allow them full control (and responsibility) of production servers.

Given this freedom, there are now a huge number of options available for deploying a Rails application, which is rare for such a new technology. So what to use? Apache + FastCGI? Lighttpd + FastCGI? SCGI? Apache 2? Litespeed? Mongrel? In what configuration? So many questions, so few answers. Here’s what I’ve been deleriously happy with, and how to do it yourself: Mongrel, Apache 2.2, and mod_proxy_balancer, using Capistrano to keep everything at your fingertips.

What the hell is Mongrel?

Mongrel is the hot new kid on the block. It’s a hybrid Ruby/C HTTP server designed to be small, fast, and brutally secure. It’s written by Zed Shaw, who is easily one of the most entertaining and delightfully cranky programmers I’ve ever read. (Zed, if you’re ever in the Bay Area, I owe you a pint.) While it’s a general purpose library, Mongrel is shaping up to be an amazing application server for Rails.

Sounds sweet. What’s Apache got to do with it?

Well, horses for courses. Mongrel is awesome at being a tight little application server for Rails, but when it comes to configurability, speed serving static files, and stability, Apache 2.2 beats the pants off Mongrel. But the main reason is that Rails does not play well with concurrency, and unless your code somehow magically gets around this, it will eat flaming death if it tries to do two things at the same time. So just Mongrel by itself would be slow at serving up static content like images, CSS files, etc., and it would necessarily be limited to a single request at a time, unless the main point of your Rails application was to publicly eat flaming death. (”It’s a feature!”)

So we’re going to be using Apache 2.2 as the front-end for Mongrel, which allows us to both serve up static content like it’s going out of style, but also to use a huge wealth of modules, like mod_deflate, which will improve your site’s responsiveness and download time. We’ll run a cluster of Mongrel servers locally, and route requests through Apache’s mod_proxy_balancer, which uses a sophisticated algorithm to make sure all the Mongrel servers feel equally loved.

Why not (Lighty|Pound|Litespeed|A Large Begonia)?

Apache is the heavy-weight in the web server world, and for good reason. It’s stable, fast, extensible, free as in Beery Speech, and all sorts of enterprisey. It’s gotten a bad rap in the Rails world, though, mainly due to its patchy FastCGI performance. It’s true, Apache + FastCGI is a horrible, horrible solution, unless your problem is “how can I waste my time on a dodgy server config?” in which case you shouldn’t be using the Intarweb while drunk. Finally, Apache currently has a great proxy balancer, which is why we’re using it.

This is not to speak ill of other front-end web servers, and you should feel free to use whatever you’re comfortable with. This article, though, is about how to set up what I’ve got set up, because I can vouch for it being awesome. Chip in on the comments if you’ve got a Mongrel band with a different lead singer and let us know how it’s going for you.

Okay, so what do I need?

I’m going to assume you’ve got Apache 2.2, Ruby 1.8.4, Subversion, and whatever database backend you need installed. That all depends on your operating system. Personally, I’ve had a great experience with Fedora Core 5, but I won’t make fun of you if you use Gentoo, Ubuntu, RHEL, Debian, FreeBSD, or whatever. Just make sure you can install and easily maintain your various pieces of software. Also, make sure you’ve got all the various low-level development tools, like a compiler or two, and the development packages for Ruby and such.

Your application has to be using either ActiveRecordStore, SQLSessionStore, or MemCached to keep track of session data. Files are the worst possible way to deal with sessions, and when you have more than one server reading and writing from the same file-based session store it’s gonna blow up big.

You should have a Capistrano script which will at least run the setup tasks correctly. If you need help with that, there are many blog articles and even a full-blown, if slightly outdated, manual on the damn thing.

Finally, none of this is going to work without root access (or an impossibly permissive server), and you’ll just piss off your admins if you try otherwise.

At this point you should have an Apache 2.2 “Welcome to Apache” style installation, and your Rails application should work just fine in WEBrick mode. If that doesn’t work, you’ve got problems which are best dealt with by tech support, IRC vets, or Friends Who Owe You Favors. If you aren’t at that stage yet, bookmark this page and get to work. I’ll wait until you’re ready.

Ready? Go!

No comments: