Saturday, June 6, 2009

Passenger and Rack

‹prev | My Chain | next›

Having played with Rack some, I think I have a firm grasp on the basics of middleware. There are two more things I would like to understand before moving on: running under Passenger and testing with Rack.

Happily, the Passenger documentation includes an entire section on running with rack so this ought to be easy.

First up, I add an entry to /etc/hosts that I will use to access the site under Passenger:       eee.local
When working locally with passenger, I like to keep the passenger configuration in my home directory for easy access. I tell apache where to find the local configuration by adding the following to /etc/apache2/apache2.conf:
Include /home/cstrom/repos/eee-code/passenger.conf
I then create home/cstrom/repos/eee-code/passenger.conf with the following contents, straight from the Passenger user's guide:
<VirtualHost *:80>
ServerName eee.local
DocumentRoot /home/cstrom/repos/eee-code/public
I tend to think that public directory is required. Since tmp/restart.txt is used to restart passenger applications, I think the tmp directory is also needed:
cstrom@jaynestown:~/repos/eee-code$ mkdir public
cstrom@jaynestown:~/repos/eee-code$ mkdir tmp
Hopefully, an apache restart will do it:

Hmmm... Not quite it would seem. Inspecting the apache error log, I find:
NoMethodError - undefined method `rewind' for #<IO:0xb71f84b8>: `call'
/usr/lib/ruby/1.8/passenger/rack/request_handler.rb:65:in `process_request'
/usr/lib/ruby/1.8/passenger/abstract_request_handler.rb:163:in `main_loop'
/usr/lib/ruby/1.8/passenger/rack/application_spawner.rb:92:in `run'
/usr/lib/ruby/1.8/passenger/rack/application_spawner.rb:50:in `spawn_application'
/usr/lib/ruby/1.8/passenger/utils.rb:165:in `safe_fork'
/usr/lib/ruby/1.8/passenger/utils.rb:163:in `fork'
/usr/lib/ruby/1.8/passenger/utils.rb:163:in `safe_fork'
/usr/lib/ruby/1.8/passenger/rack/application_spawner.rb:48:in `spawn_application'
/usr/lib/ruby/1.8/passenger/utils.rb:165:in `safe_fork'
/usr/lib/ruby/1.8/passenger/utils.rb:163:in `fork'
/usr/lib/ruby/1.8/passenger/utils.rb:163:in `safe_fork'
/usr/lib/ruby/1.8/passenger/rack/application_spawner.rb:47:in `spawn_application'
/usr/lib/ruby/1.8/passenger/rack/application_spawner.rb:33:in `spawn_application'
/usr/lib/ruby/1.8/passenger/spawn_manager.rb:110:in `spawn_application'
/usr/lib/ruby/1.8/passenger/spawn_manager.rb:247:in `handle_spawn_application'
/usr/lib/ruby/1.8/passenger/abstract_server.rb:317:in `__send__'
/usr/lib/ruby/1.8/passenger/abstract_server.rb:317:in `main_loop'
/usr/lib/ruby/1.8/passenger/abstract_server.rb:168:in `start_synchronously'
/usr/lib/passenger/passenger-spawn-server:46127.0.0.1 - - [06/Jun/2009 21:48:43] "GET /meals/2002/04/21 " 500 30 0.0005
After some googling for passenger on 9.04, I find that I need to upgrade my passenger. I had been using the stock install for Ubuntu (2.0). It looks like 2.2.2 is out now:
cstrom@jaynestown:~/repos/eee-code$ sudo gem install passenger
Building native extensions. This could take a while...
Successfully installed passenger-2.2.2
1 gem installed
Restarting apache and reloading the web page, I get another error:
[Sat Jun 06 22:11:57 2009] [notice] Apache/2.2.11 (Ubuntu) DAV/2 Phusion_Passenger/2.0.3 configured -- resuming normal operations
**** Exception ArgumentError in spawn manager (The 'app_root' option must be given.) (process 29308):
from /usr/lib/ruby/gems/1.8/gems/passenger-2.2.2/lib/phusion_passenger/spawn_manager.rb:143:in `spawn_application'
from /usr/lib/ruby/gems/1.8/gems/passenger-2.2.2/lib/phusion_passenger/spawn_manager.rb:282:in `handle_spawn_application'
from /usr/lib/ruby/gems/1.8/gems/passenger-2.2.2/lib/phusion_passenger/abstract_server.rb:337:in `__send__'
from /usr/lib/ruby/gems/1.8/gems/passenger-2.2.2/lib/phusion_passenger/abstract_server.rb:337:in `main_loop'
from /usr/lib/ruby/gems/1.8/gems/passenger-2.2.2/lib/phusion_passenger/abstract_server.rb:187:in `start_synchronously'
from /usr/lib/ruby/gems/1.8/gems/passenger-2.2.2/bin/passenger-spawn-server:61
from /usr/bin/passenger-spawn-server:19:in `load'
from /usr/bin/passenger-spawn-server:19
Ew. That look scary.

After much googling and trying of various options, I finally look closer at the log output and notice that the backtrace is for Passenger 2.2.2, but apache is loading 2.0.3. That is not likely to be a good combination. So I cd into the passenger-2.2.2 gem directory and run the installer:
sudo ./bin/passenger-install-apache2-module
Once that is complete (and I have followed the instructions for configuring Apache), I restart Apache and find:

That was a little harder than I expected, but better to find out now than when I am deploying.


  1. Yeah, unfortunately everytime you upgrade Passenger you have to reconfigure Apache to point it to the new version of it (really I think it purely the version number that is likely to change in the three lines you have to copy and paste, which makes me wonder if you could just symlink the new version somewhere and point Apache to the non-versioned number...might be easier long-term to just update the symlink).

    Anyway, as long as you remember to always ensure your boxes have the same version of Passenger and that you always update your Apache conf file after upgrading it doesn't get much easier. I was lucky enough to come into Rails world as Passenger was in its beta phases and I never had to do a lot with Mongrel, Thin, etc.

    Thanks for the informative posts. They have helped to guide more towards some new things worth learning several times the past few months.

  2. Heh, when passenger first came out, I went through the gem install / apache module install dance. Once Ubuntu included it so that I could install it via apt-get I promptly forgot. One of the benefits of this whole chain thing is that I am forced to do things that I "know" how to do, but have either forgotten or didn't _really_ know.

    I seem to recall someone doing the symlink. It might have been the peepcode screencast on passenger. That gives me an excuse to re-watch it :-)

    Glad to hear that you're finding the posts useful. I'm having fun with them for my own benefit, but it's energizing hearing that others find them helpful. Thanks!