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.





6 responses to “Replacing Mongrel with Passenger (mod_rails)”

  1. Pekka Taipale Avatar
    Pekka Taipale

    Thanks for the hint. Passenger looks very nice.
    However, there is one configuration quirk that I haven’t figured out yet.

    What I do is try to run a Rails application through a sub URI in Apache. It behaves differently from webrick. In other words: when I did run “rorapp” in webrick, I said

    $ cd ~/src/rorapp
    $ script/server

    and pointed my browser to http://localhost:3000 . This works.

    Now, with the sub URI, I have Apache document root at /var/www, and I have said ln -s ~/src/rorapp/public /var/www/rorapp. I have configured this directory with directives in Apache configuration, in a virtual host section:

    RailsBaseURI /rorapp
    RailsEnv development

    And the application starts to load, but for some reason any files the index.html.erb tries to load are fetched from server root, not from the sub URI directory! The application in Webrick mode fetches background.jpg from /images/background.jpg and this is fine, but in sub URI mode it should be fetched from /rorapp/images/background.jpg. And NO, I do not have absolute path names in my app, I have relative path names. Still, the browser tries to read them with absolute paths (I checked this with Wireshark).

    Any clues?

  2. Dave Avatar

    You are correct, things should have come from your sub URI. Stupid question, I’m sure, but did you restart Apache? I know I’ve made that mistake once or twice (OK, maybe more, but who’s counting).
    I did this for and followed the Passenger docs exactly (see In my case, only /newsscores was handled by Passenger. The rest was a simple PHP site that existed before.

    You can post more of your apache configs. Maybe I can figure something out. Feel free to email me at dave AT [this domain] if you would rather not make things too public.

  3. Pekka Taipale Avatar
    Pekka Taipale

    I got around this by using explicit tags and et cetera.
    The next problem was that in another host, I couldn’t make Rails run at all, whatever I tried. Checked a million times that Apache has got the module, experimented with load order, tried all sorts of virtual host configurations. Until I found out that in a config file for a completely different virtual host (running in the same server), the file also included a duplicate virtual host definition for the virtual host that i was using! Thus the RailsBaseURI definitions I had added and deleted so many times were all the time ignored.

    So, a lesson to be learned: be sure that your virtual host config is clear and there are no overlaps. This overlap was not done by me but another system maintainer, it had been there for a long while – it just hadn’t interfered with anything until this.

  4. Pekka Taipale Avatar
    Pekka Taipale

    Uh forgot some tags in there, so what I wrote is not visible. The explicit tags I meant werestylesheet_path “css/main.css”
    javascript_include_tag “ui.js”
    et cetera.

  5. Dave Avatar

    I don’t understand how javascript and stylesheet tags would have affected where images were loaded from, so I suspect it was the “et cetera” that fixed it.
    Good to know about the overlapped host configs. Thanks.

  6. HOWTO: Ruby on Rails with Apache + Passenger (Mod_Rails) ~ Ubuntu Lucid Lynx 10.04 - Mike's burogu Avatar

    […] Lucid Lynx (2) Phusion Passenger on Ubuntu 9.10 (3) Installing Ruby on Rails on Debian/Ubuntu (4) Replacing Mongrel with Passenger (mod_rails) (5) […]

Leave a Reply

Your email address will not be published. Required fields are marked *