Clean URLs (Permalinks) for WordPress on Lighttpd

I’ve moved my blog in the last few days to a new bigger dedicated server (as well as some other sites I own). After doing some benchmarks (I plan to post those soon) I’ve decided to switch to Lighttpd. While the exact migration notes are the topic of another post, I can say that I’m fairly satisfied with the move.

After setting up the server, I started moving the blog. Importing the files and the database was pretty straight forward. But when I thought every thing is ready and I transfered the domain to the new server I’ve found out that none of my inner pages are accessible. The reason, as it turned up pretty quickly, is that the WordPress depends on Apache’s mod_rewrite to create the clean URLs (the so called permalinks). This actually posed two problems:

  1. WordPress depends on Apache’s mod_rewrite.
  2. WordPress used .htaccess files for the clean URLs configuration

Luckily, Lighttpd has its own mod_rewrite, however it operates a bit differently. The WordPress generated .htaccess has the following lines:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

This rules tells Apache to check if the requested URL is a file or directory that exist on the server, otherwise append the requested URL to index.php. The last statement can be written in Lighttpd’s mod_rewrite syntax as

"^/(.+)/?$" => "/index.php/$1"

If we only use this rule, the posts will load up fine, but all static files will not be available, that includes CSS files and images which isn’t desired. Apache handles this by checking if the requested URL exist as a file or directory. Unfortunately Lighttpd’s mod_rewrite has no way to check if a file exists. I’ve found out that a possible workaround for this is to use mod_magent which allows to embed LUA code in Lighttpd, and use it to check if files exist and handle the clean URLs. This seemed to me an overkill, and as some people noted it has some performance hit which I wanted to avoid.

I’ve figured out that I shouldn’t just translate the rewrite rules, instead I need to adapt them. In Apache we check if a file exist in order to be able to serve the static files. The directories are checked so the server would be able to list them. The problem is now to achieve those objectives in Lighttpd. First we don’t really need to allow the directories to be listed (actually I’ve planed to block this option in my blog a long time ago). So the rule about the directories can be fully ignored. All the static files that need to be served have an extension, this includes all the files I’ve uploaded. We note that WordPress generated permalinks never have a dot (‘.’) in their URLs. So we can exploit this behavior to achieve our goal. The following condition uses regular expressions to check if a given url has an extension, and if so serves it.

"^/(.*)\.(.+)$" => "$0"

The only difference from the Apache configuration is that the web-server itself returns the 404 message when a requested file is missing, instead of passing it to WordPress and letting it return the error.

To sum everything up, our mod_rewrite configuration should look like this:

url.rewrite = (
	"^/(.*)\.(.+)$" => "$0",
	"^/(.+)/?$" => "/index.php/$1"
)

As I noted before (the second problem), there is no equivalent to .htaccess files in Lighttpd. So this configuration has to go directly into the main configuration file in /etc/lighttpd/lighttpd.conf (or where it exists in your server). Make sure you’ve enabled mod_rewrite, as this is required. You can enable it by putting the following line some where above the block.

server.modules += ("mod_rewrite")

If you have multiple sites hosted, you should use include the url.rewrite block inside a conditional statement. For example my configuration looks like this

$HTTP["host"] =~ "(www.)?guyrutenberg.com" {
	url.rewrite = (
		"^/(.*)\.(.+)$" => "$0",
		"^/(.+)/?$" => "/index.php/$1"
	)
 
	[...other unrelated configurations...]
}

And I've enabled the mod_rewrite at the top of the /etc/lighttpd/lighttpd.conf file.

This workaround works well, as you can read this post now. If you run into problems, or have any question about why or how I did soemthing, don't hesitate to comment.

53 thoughts on “Clean URLs (Permalinks) for WordPress on Lighttpd

  1. Pingback: Per’s Page » Blog Archive » Wordpress on lighttpd with pretty permalinks

  2. Pingback: raspberry pi, lighttpd and wordpress pretty permalink | Rants, grunts and chants

  3. Paul

    Setup a webserver on an old android phone this morning. Put up a WP site for the heck of it. This tutorial is amazing, thanks!

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>