At the Forge - Phusion Passenger

Run your Rails applications under Apache, using Phusion Passenger.

If you use Capistrano to deploy your programs to one or more production servers, you might be wondering how it works with Passenger. The answer is that Capistrano works just fine, but you do need to consider the layout of a Capistrano-enabled server to ensure that everything works correctly.

As you might know, Capistrano keeps several versions of a Web application around. Each version is stored in its own directory, within the releases directory. A symbolic link, called current, points to the subdirectory inside of releases that corresponds to the current version. This means that reverting to a previous version is nearly instantaneous, because it involves redefining the symlink to point to a previous subdirectory of releases.

So, on a Capistrano-enabled system, you will want your Apache configuration to look like the following:

DocumentRoot /home/reuven/current/public/

Notice the introduction of /current into the DocumentRoot. This tells Apache that it should use the current symbolic link and, thus, treat whatever current points to as the live version of the application.

But, what happens when you want to deploy a new version of your application? Capistrano is smart enough to rewrite the symbolic link, but it doesn't natively know how to restart the server. Fortunately, as we saw before, a restart involves creating the restart.txt file, so a Passenger-friendly recipe (inside of deploy.rb) could look like this:

namespace :deploy do
  desc "Restart Application"
  task :restart, :roles => :app do
    run "touch #{current_path}/tmp/restart.txt"

Now, when we issue the cap deploy command, it knows to restart the server by creating restart.txt in the application's tmp directory. If we are interested only in restarting the server, we can do so by issuing the cap deploy:restart command, which runs just the restart task inside the deploy namespace.


Passenger comes with a number of utility programs that make it easy to keep track of your server's status and resource use. The program passenger-memory-status, for example, lists all the current processes being used by Apache, as well as the number of threads that each process has spawned. It then describes the amount of memory that each of those processes is using. For example, here is the memory usage report for ten Apache processes on a production Web server:

root@kipling:~# passenger-memory-stats
-------------- Apache processes ---------------
PID    PPID   Threads  VMSize    Private  Name
2941   15559  1        11.9 MB   0.5 MB   /usr/sbin/apache2 -k start
2944   15559  2        132.5 MB  9.1 MB   /usr/sbin/apache2 -k start
7392   20753  27       234.0 MB  6.8 MB   /usr/sbin/apache2 -k start
13383  20753  2        124.0 MB  7.9 MB   /usr/sbin/apache2 -k start
15559  1      1        11.9 MB   0.5 MB   /usr/sbin/apache2 -k start
15563  15559  2        147.7 MB  8.7 MB   /usr/sbin/apache2 -k start
17357  20753  1        11.9 MB   0.5 MB   /usr/sbin/apache2 -k start
17362  20753  27       239.8 MB  12.8 MB  /usr/sbin/apache2 -k start
17477  20753  27       236.6 MB  7.8 MB   /usr/sbin/apache2 -k start
20753  1      1        11.9 MB   0.4 MB   /usr/sbin/apache2 -k start
### Processes: 10
### Total private dirty RSS: 54.95 MB

That same command also shows us the current memory status for our Passenger (that is, Ruby) processes. It shouldn't come as any surprise to learn that the Ruby processes typically will be much larger than the Apache ones. Indeed, monitoring the memory usage of the Rails processes is an important thing for Rails developers to do; without such feedback, it will be difficult to measure how efficiently processes are working.

Other Apache Modules

Finally, as I mentioned previously, one of the best parts of using Apache for Rails applications is the fact that you can mix and match other Apache modules, as you like. For example, I am a big fan of both mod_status and mod_info, two modules for Apache that make it possible to peek into the server's current configuration and execution state.

In the same way, I wanted to compress files automatically as they were sent from my server to the user's browser. By incorporating mod_deflate into my server configuration, I was able to add automatic, on-the-fly compression with the following directive:

SetOutputFilter DEFLATE

Finally, I recently worked on a simple Rails site that wanted to restrict access to items under the /admin URL to authorized users. I could have used a Rails plugin, such as restful_authentication, but as I was using Passenger, I thought it might be just as easy and fast for me to use HTTP authentication on the site, defined in the Apache configuration file. Sure enough, the following was enough to do the trick:

<Location /admin>
  AuthName "Site admin"
  AuthType Basic
  AuthUserFile /opt/mysite/users

  require valid-user

Of course, you could argue that this sort of authentication is far less flexible than a Rails-based one, and you would be right. But for a site that has very simple needs, and that doesn't need something as fancy as restful_authentication, Apache's built-in (and well documented) HTTP authentication is a good solution.