Because, Let’s Face It, Webrick Sucks
My favorite new web server is a real dog. No, really. And it’s no poncy purebred, either—it’s a Mongrel.
Goodbye, Webrick
Webrick is the built-in Ruby web server that is the default for each Rails app you create or download—when you type script/server
, that’s what it’s running, unless you’ve configured it otherwise.
It used to be that Webrick was the only suitable thing to run Rails in when you’re development, and it required no configuration. Then people started using lighttpd even for development mode, because of Webrick’s many flaws, but lighttpd isn’t the easiest thing to get working. I, for example, gave up on it after a few hours because nobody could track down the error I was getting. Blow that for a lark, said I, I’d rather use crappy Webrick because at least it’ll start.
But the problem with Webrick is not that it won’t start, because it will start; the problem is that it’s really, really slow. And not only slow, but buggy.
<span id="more-8062"></span>
Development Mode is for Smart People, Not for Webrick
When you run a Rails app in development mode, it’s supposed to reload every single Rails file every time it’s called for—in production, it caches stuff like your model classes, and an internal representation of the database table attached to the model. This makes development mode slow by nature, but really great when you’re actually working on an app. The point of development mode is that you don’t have to restart your web server just because you added a column to one of your database tables.
In development mode, though, it’s not at all uncommon for Webrick to not reload files it should, or check out the database again like it should. Not only does it get progressively slower with each reload! No, on top of that, many of us have pulled out hair trying to figure out how our change isn’t working, only to find it’s because Webrick’s not behaving and it needed to be restarted.
Basically, it’s a crappy experience. Fairly unRails-like, even.
Enter Mongrel
Mongrel is another lightweight web server for Ruby apps, much like Webrick. Except it doesn’t suck. Mongrel is so fast that it’s actually good for parsing Ruby apps (like, I dunno, Rails!) on production servers.
Let me repeat myself:
Mongrel is Fast!
And it’s easy to install:
$ sudo gem install mongrel
And it’s easy to run in the background:
$ cd myrailsapp
$ mongrel_rails start -d
It’s also easy to stop:
$ mongrel_rails stop
Or run with its logging to your terminal window:
$ mongrel_rails start
Mongrel also runs on port 3000 so your Rails app should be available at http://localhost:3000/
if it’s running on your current machine.
Zed Shaw is My Hero
He may be grumpy, but he made Mongrel and so he’s secured himself a special place in my heart.
Your comments were a bit of a shock, as I’ve never had any of the problems with Webrick that you describe during Rails development. But it is slow, so maybe I’ll give Mongrel a shot.
Brian, it seems like not everyone gets bitten by that bug but I’ve seen it happen to plenty of people (including myself). It’s extremely unpleasant when it does 🙂
What I don’t quite understand is the real, functional difference between Lighttpd and Mongrel? I’ve never had a problem getting lighttpd to work, so I never had to "settle" for webrick.
It seems that mongrel is the new hotness, but I don’t see why I should bother checking it out if lighttpd works as advertised. Did you ever get LIghttpd working on your setup? If so, I’d be curious as to why you switched.
Considering webrick sucks, and mongrel is rather new, what were you using for a production server?
Sorry about all the questions, I am just really curious about mongrel, but no one seems to be able to tell me the why of it all.
Cheers!
Because you have to run FastCGI under lighttpd to interpret Ruby code at any reasonable speed, and Mongrel is faster yet than FastCGI and easier to do load balancing for.
You can also run Mongrel behind lighttpd
Ooh, I just installed the gem, and it’s so much faster! I’ve heard about Mongrel, but I didn’t realize it was so easy to install and use for Rails dev. Thanks Amy.
Thanks for this Amy. I’ve recently been bitten by the "not reloading" problems with webrick. I spent two hours searching for problems in my code before giving up. I went back the next day and it worked! Obviously webrick was not reloading my code correctly 🙁
Thanks for this.
Mongrel is great, but Lighttpd is no longer recommended by Zed as a front-end for Mongrel, due to mod_proxy issues. I’m "now using LiteSpeed":http://blog.alisonrowland.com/articles/2006/06/03/deployment-on-the-brain with Mongrel and couldn’t be happier.
Fair enough, Alison — it was still listed as "lighttpd" in the diagrams I looked at the other day on the mongrel site, guess we should bug Zed to update them. 🙂
The only thing keeping me from Mongrel at the moment is that it requires Ruby 1.8.4. Since my host (dreamhost) is still using 1.8.2, I like to develop in the same version. Now maybe I should just upgrade my version on my machine, because I’m not really sure of any differences between 1.8.2 and 1.8.4. If there are any, they’re probably minor, but I’m not quite ready to take the chance. So until I get myself onto a non-shared host, I suppose I’ll have to stick with Webrick.
I’m very curious about using mongrel; does anyone know if the reported performance problems on OS X have been fixed?
"Because you have to run FastCGI under lighttpd to interpret Ruby code at any reasonable speed, and Mongrel is faster yet than FastCGI and easier to do load balancing for."
Aha! This sort of info was exactly what I was looking for.
Thanks so much.
I’ve been using Mongrel for a couple of months now (only in development – I haven’t actually "launched" any Rails apps – libraries move slowly, see) for exactly the same reasons as you. I never could get lighttpd working and webrick’s performance made me scared that my app was going to be so slow that nobody would ever use it (I didn’t have the bugginess).
Mongrel has been… incredible. Anything that goes from "discovery of its very existence" to "getting my application running stably and exponentially faster" in less than 10 minutes (7 of which was spent reading the site before installing the gem) is a must-have in my book. I must have wasted a week’s work trying to get lighttpd to work.
Even for the files I add outside of the script/generate method (I have a ton of models that are based on web services), stopping and restarting mongrel is so fast it doesn’t really bother me.
If you’re on OS X, use <A href="http://locomotive.raaum.org/">Locomotive</a>, which lets you use Lighttpd in development mode with no setup or configuration.
Ahhh, thanks Amy for giving me the kick in the ass that I needed to try Mongrel out. It’s been love at first page load! 🙂
Being a Linux/Ruby/Rails newbie, this might be a stupid question, but is it possible to set it up so that script/server would start Mongrel instead of WEBrick?
Thanks for the article. Being absolutely new to ruby I appreciate finding articles that compare various offerings within ruby, otherwise a newcomer has to try out many softwares/libraries to find out what works, what sucks, what’s abandoned.
e.g. the confusion of whether to use mod_ruby, cgi, fcgi,ruby-web and ruby-cgi. Each means installing, configuring etc, subscribing to lists, before one can decide.
Again, for accessing databases and getting database metadata i spent a lot of time playing with OG, rails, mysql-ruby and DBI to find what met my needs.
If experienced folk like you can give us comparisons (and if these could be posted on the main ruby site) it would help newbies a great deal.
Amy, thanks for this. What do you use in production?
Thanks for the tip with Mongrel. Best part might be that I will be able to install a production server even when the ISP is clueless to how to install Ruby on Rails along with Apache.
This will be good… and yes, fast 🙂
@Kyle Heon:
I wrote a quick script to run Mongrel with @script/server@ instead of Webrick. Here’s the condensed, super-simple version:
<pre><code> command = ‘mongrel_rails start’ exec command + ARGV.join(‘ ‘) </code></pre>
However, a more substantial and flexible option (sans comments) is:
<pre><code> argv = ARGV.dup if File.exists?(File.dirname(FILE) + ‘/../log/mongrel.pid’) pid = "" File.open(File.dirname(FILE) + ‘/../log/mongrel.pid’) {|f| pid = f.readline} else pid = false end if (pid != false) && (ARGV[0] == ‘stop’) command = "echo ‘Mongrel stopping…’;kill " + pid + ";echo ‘Mongrel stopped.’" argv = [] elsif (pid != false) command = "echo ‘\nMongrel is running with PID " + pid + "’\necho ‘Use \"script/server stop\" to stop\n’" else command = ‘mongrel_rails start ‘ end exec command + argv.join(‘ ‘) </code></pre>
Usage is simply calling @script/server@. Add any @mongrel_rails@ options as necessary. I commonly use @-d@. When this option is used, you can kill Mongrel by calling @script/server stop@. (Call @script/server@ when running in daemon mode to get the PID.)
To use, simply comment out the last two lines of your @script/server@ file(s) and add in the lines above (depending on how you run Mongrel and your preferences).
M.T.
I’m not sure what’s going on, but different web servers send different information to the terminal window for me:
Anyone else come across this? I’m using Rails 1.1.2 with Ruby 1.8.4 on a MacBook Pro (i.e. Intel-based Mac) running MacOS X 10.4.6. I’d like to give Mongrel a more extended try, but I’m not willing to give up seeing the log in the terminal window.
I’d also like to correct a misconception that seems to be very common in the Rails community lately. In point of fact, as of Rails 1.0, LightTPD, not WEBrick, is the default web server for Rails, unless you’ve configured it otherwise. (Of course, if you don’t have LightTPD installed, script/server falls back to WEBrick, but given the choice, script/server will always launch LightTPD first.)
@Chris Gernon
With Mongrel, you can simply call "mongrel_rails start -d" to start it in daemon mode and tehn simply call "tail -f log/mongrel.log" (I believe that’s the log file).
But, aside from this, if you’re using Lighttpd and it’s working for you, that should be fine. I wouldn’t recommend changing, really, if you like what you’ve got.
M.T.
The odd thing about the Mongrel log is it doesn’t show the referral IP…or is there a way to do this? I’d like to see a more "standard" apache/lighty style access log
Mongrel rocks my face
Hi Amy,
I have setup a production server using Apache2.2 with mod_proxy_balancer and a cluster of Mongrel servers and it runs like lightning !!
I created a doc while doing it as the tech-support guys at Rimuhosting were keen to see how I got on. It’s a little rough around the edges, but if you or your readers would like a copy then just drop me an email or leave a comment on the blog.
It’s based around the Ubuntu 6.06 distro but should work on any with very little modification.
-Mic
That was great Amy.
My hair turned white trying to get LightTPD work. The promise of speed made risk my appearances.
Mongrel work like a dog!
PS: Mongrel site should carry your 3-line howto.
My first problem with webbrick came while reading the Agile Web Dev 2nd ed book. Had to restart the server after adding in some ajax.
Mongrel sounds great =P, I’ll give it a try.
I have been using Mongrel setting up easily on Windows 2003 server on the services, and its works like a charm so far. My webrick suddenly didn’t work complaining about "bad file descriptor". Now I am using Mongrel for development and testing. Also didn’t got lighttpd working either. I am thinking seriously about using clustered Mongrel for production also.