bradleyboy :: the online home of Brad Daily

CakePHP, Lighttpd and ModMagnet

Since finding Rails a few years back, I have grown more and more fond of lighttpd (aka lighty), a lightweight, fast alternative to Apache. Now that I spend some time back in the land of PHP (in particular CakePHP), I wanted to try and get a CakePHP app up and running using lighty instead of Apache. Here’s a walkthrough…


Prerequisites
First, you will need to have lighttpd installed, 1.4.12 or above or anything in the newer 1.5.x branch. I’ll be delving into ModMagnet here, so you will need to have lua installed (5.1 or greater) and have lighty compiled –with-lua.

Why ModMagnet?
One of the first things you have to do when moving from Apache to lighty is transition your use of Apache’s fantastic ModRewrite to a suitable replacement in lighty land. The most obvious candidate is lighty’s own rewrite module, but it lacks some of the more advanced features of Apache’s module, notably Apache’s rewrite condition statements.

ModMagnet is a newer module in lighty and aims to give a lot more flexibility to handling, rewriting and forwarding requests. Since we needed to do a lot more than just the standard CakePHP rewrites, ModMagnet fit the bill perfectly.

Let’s look at our lighty configuration. First and foremost, make sure you have ModMagnet in your list of modules to load:

Code (lighttpd)
  1. server.modules = ( …, mod_magnet, … )

Also, for the purposes of this demo, we have our document root set to the webroot foldler of our Cake application:

Code (lighttpd)
  1. server.document-root = "/path/to/cake/app/webroot/"

Now, we want to tell ModMagnet to attract (get it…it’s a magnet!) any request that comes down the pipe:

Code (lighttpd)
  1. magnet.attract-physical-path-to = ( server.document-root + "/rewrite.lua" )

This will take any request that is made and pass it directly to the rewrite.lua file, which is placed in our document root.

What a minute…Lua who?
That’s right, ModMagnet uses Lua, a fast, lightweight scripting language that works really well in this environment. You can read more about Lua here.

Writing the Lua Script
Our needs are simple. We want to check if the file requested actually exists on the filesystem. If it does, simply serve up that file without invoking PHP and FastCGI. If the file does not exist, we want to rewrite the request to CakePHP.

Code (lua)
  1. – rewrite.lua
  2.  
  3. – Does file exist on file system?
  4. attr = lighty.stat(lighty.env["physical.path"])
  5.  
  6. – It does not
  7. if (not attr) then
  8.   – Pass request to CakePHP’s index.php
  9.   lighty.env["uri.query"] = ‘url=’ .. lighty.env["uri.path"]
  10.   lighty.env["uri.path"] = "/index.php"
  11.   lighty.env["physical.rel-path"] = lighty.env["uri.path"]
  12.   lighty.env["physical.path"] = lighty.env["physical.doc-root"] .. lighty.env["physical.rel-path"]
  13. end

That’s it! The lighty.stat() call attempts to stat the file, and if it fails we form the path and query string just like CakePHP likes it. The request then is taken back by lighty and continues to completion. There is a lot you can do here, be sure to check the ModMagnet docs for all the variables available.

You are reading an archived post, written on Friday, June 15th, 2007. Feel free to leave a comment or trackback from your own site.

» Next post:
   Introducing: Farkleberrys

« Previous post:
   Screencasts for perfectionists

3 Responses to “CakePHP, Lighttpd and ModMagnet”

  1. Brendon Says:

    Here is another alternative solution to getting CakePHP 1.1x working with Lighttpd 1.5x:

    http://thefaultandfracture.blogspot.com/2007/10/enabling-cakephp-11-on-lighttpd-15.html

  2. Vic Says:

    Great article, got Lighttpd to work with CakePHP 1.1 and mod_magnet
    Only question is how do you get the css files to work?

  3. Yosip Curiel Says:

    Be aware with the ‘ symbol this generate a 500 error. The ‘ symbol must be used instead
    This is how it should be

    lighty.env["uri.query"] = ‘url=’ .. lighty.env["uri.path"]

    instead of

    lighty.env["uri.query"] = ‘url=’ .. lighty.env["uri.path"]

    The complete code:
    attr = lighty.stat(lighty.env["physical.path"])
    if (not attr) then
    lighty.env["uri.query"] = ‘url=’ .. lighty.env["uri.path"]
    lighty.env["uri.path"] = “/index.php”
    lighty.env["physical.rel-path"] = lighty.env["uri.path"]
    lighty.env["physical.path"] = lighty.env["physical.doc-root"] .. lighty.env["physical.rel-path"]
    end

Leave a Reply