Mephisto with Phusion Passenger

I recently upgraded my blogging software,
Mephisto, from 0.7.3 to 0.8.1. One thing I
noticed is that they moved the cached files from public to a cache
subfolder containing the site. For example, on a new installation, the
cached index page is in public/cache/unusedfornow.com/index.html.

Mephisto writes a cached page for every page visited. This means that
any subsequent requests for this page can be served directly by apache
from the cached file rather than going through the whole rails stack
(all the way down to the database). This is much faster and uses less
memory.

I run my blog in Apache with Phusion
Passenger
. The problem with this new cache
location is that Passenger only looks in public for cached files. This
means that the cached pages are ignored and every request is being
served by Rails. After searching google and working some mod_rewrite
magic, I came up with the following solution. Here is the Apache virtual
host configuration for my blog:


    ServerName pgrs.net
    ServerAlias www.pgrs.net

    DocumentRoot /var/www/mephisto-0.8.1/public

    RailsAllowModRewrite on
    RewriteEngine On

    # Rewrite / to index.html
    RewriteRule ^/$ /index.html [QSA]

    # Rewrite /some_page to /some_page.html
    RewriteRule ^([^.]+?)/?$ $1.html [QSA]

    # If cached file exists, serve it and stop processing
    RewriteCond %{DOCUMENT_ROOT}/cache/unusedfornow.com%{REQUEST_FILENAME} -f
    RewriteRule ^(.*)$ /cache/unusedfornow.com$1 [L]

    ErrorLog /var/log/apache2/pgrs-error.log
    CustomLog /var/log/apache2/pgrs-access.log combined

The first 3 lines are standard Phusion Passenger configuration:
Deploying a Ruby on Rails
application
.
Then, I turn on mod_rewrite. The first two sets of mod_rewrite
configuration cascade and turn the request into what the filename will
look like. So / becomes /index.html, and
/2008/10/29/deploying-trunk-or-tags-with-capistrano becomes
/2008/10/29/deploying-trunk-or-tags-with-capistrano.html.

The final set checks if this file exists under
/var/www/mephisto-0.8.1/public/cache/unusedfornow.com (the -f flag), and
if it does, tells apache to serve this file. The [L] tells
mod_rewrite that this is the last rule, so it should stop processing
now. If the file does not exist, the request falls through mod_rewrite
and Passenger picks it up and serves it through Rails.

I verified that this works by looking at the response headers in Firefox
(Tools -> Page Info -> Headers) of any given blog page. The first
time, there is a “X-Powered-By: Phusion Passenger (mod_rails/mod_rack)
2.0.3” header. Once I refresh, the X-Powered-By header is gone since the
request never makes it to Passenger. Apache is once again doing the hard
work, and Rails is only used when the request is new or dynamic (such as
searching).

Paul Gross

Paul Gross

I'm a lead software developer in Seattle working for Braintree Payments.

Read More