Hosting Ruby on Rails with Passenger
Posted by David December 16, 2008 @ 12:31 PM
Phusion Passenger aka mod_rails has been on a tour de force lately and rightfully so. It makes Rails deployment so much simpler and combined with REE faster and with less memory overhead. So I’m really happy to see that lots of the hosting companies in the Rails world are adopting it and making it available to their customers.
Rails Machine recently announced that Passenger is now part of their standard stack and that they’ve made it silly easy to switch from a Mongrel-based setup to Passenger. The latest Accelerator from Joyent has Passenger preconfigured as well. At the shared hosting end, Dreamhost has been supporting Passenger for a while (nice tutorial using Passenger at Dreamhost).
I’ve personally been setting up Passenger at Slicehost with Ubuntu and having great results with that. At 37signals, we’re already running Ta-da List (on EC2) and Backpack (at Rackspace) on Passenger and plan to move over the rest of the applications shortly. Our system administrators certainly appreciate not having to funk with Mongrels any more.
Lots of other hosters are in advanced testing with Passenger as well. Brightbox has been building Ubuntu packages for Passenger and is putting one together for REE. They should have complete Passenger support shortly. Most other Rails hosters I’ve talked to are at least looking into it as well.
But just because Passenger is a big step forward for Rails hosting, it doesn’t mean that other approaches are suddenly useless. There may still be situations where a traditional proxy/Mongrel setup would be relevant. For example, if you for some reason are unable to use Apache, that’s still the way to go. Rails will continue to support both FCGI, proxy/Mongrel, any Rack web server, and of course Passenger.
The change is that if you do not already have an investment in an alternative solution, or if you’re feeling pain with that solution, you should definitely consider Passenger to be the default choice for Rails.
Update: Phusion has posted a guide to how you control the Rails and Ruby environment variables under Passenger. Useful for tweaking the GC settings etc.

Shame about Engine Yard. :-(
I still prefer Mongrel. If you’re using Passenger, you have to deal with some drawbacks in using Apache and mod_rewrite and such. Read section 6.4. “Conflicting Apache modules”.
For Brazilians, count Locaweb in: http://www.locaweb.com.br/rails/, the biggest Latin America web hosting company supports Phusion Passenger for 6 months already. Passenger is awesome!
Passenger does have issues. It screws up your gem search path. You can’t run the debugger with it.
I switched all of our production, staging, and dev/test to servers to Passenger + REE a couple months ago and I have no regrets. Our application really benefits from the dynamic spawing of new servers on demand.
However, I am wondering how do you guys tweak the REE + GCPATÇH tunables when using Passenger in production? Do set these in each application’s environment.rb ? Since Passenger is spawning the REE ruby instances it’s not clear to me where to set these.
Passenger is an awesome tool, but it’s a shame there’s no comparable system for Nginx. I’d much prefer to use Nginx than Apache due to it’s speed, low memory usage, and stability. (although to be fair Apache is extremely stable too)
The Passenger guys have said that they’ve managed to tweak Apache to the point where it’s comparable to Nginx, but I haven’t seen any published proof yet. In my experience, given the same workload, Nginx is much faster at serving static content than Apache and uses much less memory.
Ezra from Engine Yard posted a comment on the Phusion blog that EY would like to fund development of a Passenger plugin for Nginx. I don’t know what’s come of that, but if it happened I think it would be awesome for the community to have a choice between Apache and Nginx when using Passenger. (If Phusion isn’t interested, maybe a “code bounty” should be made for a comparable Nginx plugin)
We switched all of our applications (a couple minor production apps + staging for each + a ton of demo apps) over to Passenger from Thin about a week ago and are really really happy with it.
We are currently using Nginx as a front end to proxy off to a completely stripped down version of Apache. This allowed us to essentially keep the same configs we were using for Thin while only needing to change the upstream.
For an example here is the Munin graph for our staging + demo box: http://skitch.com/gaffers/6sfa/munin-thin-to-passenger
I will second the lack of ruby-debug support for development (but script/server is always there).
I wrote an almost automated script that sets up Apache2 with Passenger and REE on Ubuntu: http://gist.github.com/32917—saved me a lot of time.
@Andy: Passenger instances happen to run in an environment that can be different than the one in your console. That probably screws up your GEM_HOME.
We’re doing the same thing as gaffneyc – left nginx where it was (especially there is some configuration and module use there) and just replaced each virtual machine full of Thins with a single stripped down Apache + Passenger. I’m very happy with the result.
I was also wondering about the GCPATCH stuff. Phusion blogged that you guys were using it and I’d love to know 1) how much it helps 2) what settings you use and 3) how do you configure REE/Passenger to use the GC settings?
@Andy, Dan, Casey: check http://blog.phusion.nl/2008/12/16/passing-environment-variables-to-ruby-from-phusion-passenger/
I think I’m allergic to config files that look like the unholy lovechild of XML and bash syntax, so I definitely fall into this category. It’s probably a genetic predisposition.
I’ve never minded Apache configs all that much. My biggest complaint is that all of the Unix distros I’ve worked with (Gentoo, Debian/Ubuntu, RHEL/Fedora/CentOS, OSX Server) they each manage their config layout differently.
For a program that is fairly ubiquitous it’s surprising that there is no standard for this.
@Hongli Lai: Thank you!
I too have been using Passenger at Slicehost with Ubuntu and am very happy with the process and the results.
I recently began deploying production Rails app, initially following along with “Deploying Rails” and running mongrels behind apache, with Monit to bounce errant mongrels. This already smelled fishy (i.e., like Windows) to me and it didn’t work very well. I swapped mongrels for Passenger and have been very pleased.
I think running nginx up front to serve static content and balance requests across apaches running Passenger is probably the easiest to manage, efficient solution out there right now.
Passenger is great. And we I use it on a bunch of my rails sites.
However, a big problem is not being able to use mod_rewrite.
Stupid simple things like being able to set a cononical url (www consistently, for example), is not possible.
I wish there were a way around this, maybe I am missing something?
It seems there’s always “four parts” of pain, no matter what, it just gets shifted around:
In this case, passenger shifts the pain to the server admin… for us, every time I’ve gone to install it, on each of the three servers, installing passenger involves a recompilation of Apache… not exactly a walk in the park if you’ve got a live, running server.
-grumble- MPM fork blah….- Sensei.
On my blog you could find more info about configuring mod_rails, and mix it with mod_jk or php.
sensei: Passenger is compatible with both the prefork MPM and the worker MPM so I’m not sure what you’re talking about.
The mod_rewrite/mod_alias conflicts are certainly annoying.
If you front your passenger apaches with nginx (or your http server of choice, including a separately tuned apache) for layer seven balancing and/or for serving static content, you can handle your rewrites up front before the request passes through to the apache/passenger daemon.
Serving 3 million pageviews a day off Passenger.
This is my first time scaling and all I’ve had to do on the Apache/Passenger side is increase the number of instances. Beautiful. One less thing to worry about.
So does Passenger work in an environment like Amazon EC2 where you want to dynamically scale the App (ie number of rails instances) accross many virtual hosts?
Do you have to use Apache instances per host and do load balancing on top of that?