Replacing Mongrel with Passenger (mod_rails)

I've been using Apache + Mongrel for a while now. I read about Passenger when it first came out, but I never felt the need to bother with it since I have a bunch of recipes for Apache and Mongrel (see a previous posts about background tasks with Workling). The other day, I figured I would give it a shot. Now, I think I found my new way to deploy Rails apps. It is so simple, and it works well. Some people write off Passenger because it uses Apache and not Nginx. Nginx is a little faster, and it is the latest "best practice," but I haven't had issues with Apache in forever. As for the speed issues, I don't see it being a big factor to the end users. A few milliseconds is not going to be noticeable, at least for my apps.

Installation could not be simpler.

  1. sudo gem install passenger
  2. sudo passenger-install-apache2-module
  3. Follow the instructions the previous script displays
  4. Restart Apache
  5. Done!

If your development machine is OSX, don't bother to manually change the Apache conf for your application and your hosts file just yet. You can use the Passenger Preference Pane instead. This little beauty will make all the changes to your Apache config files for you. One of the benefits is that you can have dozens of small Rails projects configured, and all are available with their own url -- no need to run script/server for each. For install, the site explains it pretty well, so I won't go into it here.

I did run into one problem on my Leopard machine. My default Apache config file had the httpd process running as the _www user, but my project files are owned by me. The result is that I kept getting permission errors accessing files in my project. I'm sure there is a solution to the problem by changing the permissions on my project files, but I didn't find it. I ended up running httpd as me, and that fixed it. I did not have this issue on my test or production systems.

Even with the problem, the entire process took me less than an hour. What I gained is the following:

  • I no longer have to run script/server every time I switch to a new application for development.
  • All of my apps on my dev machine have their own url (myapp.local, etc.) instead of localhost:3000.
  • My god.rb config no longer has to watch Mongrel processes. It's all in Apache.
  • No Mongrel cluster or load balancing in Apache configs among multiple Mongrels. Apache just operates normally, and my config files are a lot simpler.
  • Mongrel hasn't had any updates in while, but Passenger is still under active development.
  • An added benefit is that my test/staging server performs better since only the applications being used are running. By default Passenger will drop any process not accessed in 300 seconds (you can change that).

All of the required changes involved removing any references to Mongrel in my god.rb config, apache config, and my deploy.rb. The only thing I needed to actually change is how to start/stop/restart my application. Remember, there is no mongrel process to start or stop. It's all Apache. Passenger makes it easy, however. All you need to do is touch tmp/restart.txt. If that file is modified, then Passenger will restart your application.

My updated config/deploy.rb:

namespace :deploy do

  desc "Start the application"
  task :start, :roles => :app do
    run "touch #{current_release}/tmp/restart.txt"
    sudo "god start listeners"

  desc "Stop the application"
  task :stop, :roles => :app do
    # Do nothing for application
    sudo "god stop listeners"

  desc "Restart Application"
  task :restart, :roles => :app do
    run "touch #{current_release}/tmp/restart.txt"
    sudo "god restart listeners"

Give Passenger a try. I think you will like it.