Implementing the Front Controller Pattern in Lighttpd

One of the more common design patterns in installable web applications today is the Front Controller pattern. Unlike other web applications that have separate files to respond to specific requests, the front controller pattern funnels all requests through a single file, and that file processes the requested URL to respond as appropriate.

In typical scenarios, you'll accomplish this with Apache using a set of mod_rewrite directives. These directives first check to see if the requested file or directory exists. If it does not exist, then the request is passed on to the front controller. This allows requests for existing files - like images, stylesheets, and client-side scripts - to be requested directly rather than passing through the URL rewriting mechanism.

If you are familiar with implementing a front controller using Apache, you will recognize these directives, which are commonly found in an .htaccess file within the application directory:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [PT]

I have been running a low-budget VPSLink server for a few months. The server is a complete Virtual Private Server (VPS) to which I have root access, and it only costs about $7 per month - less than the price of many less feature-rich shared hosting plans. The downside of such a cheap server is that it only has 64MB of RAM and 2.5GB of drive space to work in. In short, it doesn't have the requisite resources to run both Apache and MySQL.

As you might be aware, there are other web servers available. A web server of particular interest is Lighttpd, which is a small, fast web server that seems perfect for the needs of this small VPS. Because the disk and memory footprint of Lighttpd is so small, I can run an efficient web server on this tiny VPS without an issue. But one problem's solution had eluded me until recently, which is how to enable the front controller on Lighttpd.

Lighttpd does not use the same directives as Apache. Instead, they have a completely different mechanism for configuring the server. After much research, trial, and error, I think I have come across a combination of directives that result in a working front controller.

First, the configuration must enable the mode_rewrite module. This is named the same as the Apache module, but is different for the Lighttpd server. Add this module to the server.modules list:

server.modules = (
"mod_access",
"mod_alias",
"mod_accesslog",
"mod_fastcgi",
"mod_rewrite"
)

With that module enabled, you can set rewrite rules that enable the front controller. The tricky part to solving this is to also allow requests to files that exist to pass through the rewrite so that they are not rewritten. I believe that the following rules will successfully accomplish this task:

url.rewrite-once = (
"^/(.*)\.(.*)" => "$0",
"^/([^.]+)$" => "/index.php",
"^/$" => "/index.php"
)

In concert with these Lighty rules, I have configured the server to use SQLite instead of MySQL. (There simply isn't enough memory to run MySQL on this small server, even with the web server completely disabled) Using Lighttpd and SQLite on the server allows me to run a Habari instance on this super-small, custom-configured server for about $7/month. When using Habari with the Flickr silo plugin, I can host the bulk of my photo resources at Flickr where the bandwidth and storage space are plentiful, leaving me with a clean, fully-featured server.

Running a tight server where the server itself was running only the necessary services and a content delivery network was hosting the bulk of my content has been a goal of mine for quite some time. Prior to these configuration options, I had been able to do this only on more expensive VPSes or flaky shared hosting. With this configuration, I can have the best of both worlds - a cheap and full-featured blog server.


3 Responses to Implementing the Front Controller Pattern in Lighttpd

  1. owen from asymptomatic.net 1970-01-01T00:00:00+00:00

    The Habari instance I mentioned is currently running smoothly on my VPSLink test server.

  2. owen from asymptomatic.net 1970-01-01T00:00:00+00:00

    Two more notes while I'm thinking of it.

    Note 1: You can also accomplish the front controller implementation in Lighttpd using a 404 handler. In this case, you simply set the 404 error page to the script of your front controller. The problem with this is that it interferes with logging (since all requests to valid pages will be logged as a 404) and also potentially sends the wrong HTTP result (a 404) to the requesting browser. This can muck up your search engine results. For these reasons, and since I think I've found this working alternative, I don't believe that using the 404 handler is a reasonable/reliable way to configure the server.

    Note 2: Although you can use this configuration to enable a WordPress (or other blog software) install on Lighttpd, WordPress doesn't use multiple databases by default, only MySQL. One of the bigger issues with a server as small as the VPSLink Link-1 is that you simply can't run MySQL in it - the server won't even let you install it. As a result, only blog applications that allow alternate data storage, like SQLite or flat files, will run on such a small server. Meaning that this is just another of the growing pool of things that Habari can do that other blog tools can't - save you money. ;)

  3. Matt Read from mattread.com 1970-01-01T00:00:00+00:00

    I have a little update for the rules. I was having a problem where the query string was parsed with the first rule, so something like ?var=foo-bar-1.2.4 it would not send it to habari. So here are my rules to account for the query string:

    url.rewrite-once = (
    "^/([^\?]+)\.(.*)" => "$0",
    "^/(.+)$" => "/index.php",
    "^/$" => "/index.php"
    )
2713