lighttpd on Ubuntu - alias.url doesn't work when included in a module config file
December 09, 2007 [Tech]I've decided to use lighttpd on my new machine (which was generously given to me and features a 700GB raid array).
My main reason for choosing lighttpd was the FLV streaming plugin for it that will make my Wii TV viewing experience a lot better. (It works - I've tried it!)
However, if I'm going to use lighttpd for streaming TV to my Wii, I want to use it for everything, rather than having Apache running as well. In any case, I think given my load pattern (average 0.01 users at any time, approx) a lower-memory (but maybe less stable under heavy load) solution seems a good choice.
So I have to get my webmail, home-grown address book, and mediawiki installations all working with lighttpd. How hard can it be?
Actually, harder than it should be.
Lighttpd is supposed to listen to a directive that looks like this:
alias.url += ( "/mediawiki/" => "/usr/share/mediawiki1.10/" )
and on Ubuntu, being Debian-derived, you can split your lighttpd config into separate files, allowing apt to modify the main config file during an upgrade without blatting your customisations.
So I created a file in /etc/lighttpd/conf-available/ called 50-mediawiki.conf that contained the alias-url line above, and then I ran:
sudo lighty-enable-mod mediawiki
and a symbolic link was duly created at /etc/lighttpd/conf-enabled/50-mediawiki.conf.
I restarted lighttpd like so:
sudo /etc/init.d/lighttpd force-reload
and navigated to localhost/mediawiki, but got a 404 error.
A lot of experimentation later, and it turns out to be a stupid thing.
Lighttpd has a stupid "by design" behaviour, which I think I can summarise as "if you encounter a change to alias.url that comes AFTER a conditional that modifies alias.url, ignore it."
So, to explain by example, this code in /etc/lighttpd/lighttpd.conf will successfully redirect /test/ to /home/andy/test/:
alias.url += ( "/test/" => "/home/andy/test/" ) $HTTP["remoteip"] == "127.0.0.1" { alias.url += ( "/doc/" => "/usr/share/doc/", "/images/" => "/usr/share/images/" ) $HTTP["url"] =~ "^/doc/|^/images/" { dir-listing.activate = "enable" } }
but this code:
$HTTP["remoteip"] == "127.0.0.1" { alias.url += ( "/doc/" => "/usr/share/doc/", "/images/" => "/usr/share/images/" ) $HTTP["url"] =~ "^/doc/|^/images/" { dir-listing.activate = "enable" } } alias.url += ( "/test/" => "/home/andy/test/" )
Will leave you scratching your head as to why it doesn't work.
Since the bit of lighttpd.conf that is put there by Debian (or Ubuntu?) to include all files in conf-enabled/ comes at the very end of the file, any alias.url lines in any module config are ignored. Clever eh?
To skip to the end, my fix was to move the Debian documentation code to the very end of the config file, so the end of lighttpd.conf now looks like this:
... #### external configuration files ## mimetype mapping include_shell "/usr/share/lighttpd/create-mime.assign.pl" ## load enabled configuration files, ## read /etc/lighttpd/conf-available/README first include_shell "/usr/share/lighttpd/include-conf-enabled.pl" #### handle Debian Policy Manual, Section 11.5. urls #### and by default allow them only from localhost $HTTP["remoteip"] == "127.0.0.1" { alias.url += ( "/doc/" => "/usr/share/doc/", "/images/" => "/usr/share/images/" ) $HTTP["url"] =~ "^/doc/|^/images/" { dir-listing.activate = "enable" } }
Now my separate file for mediawiki works fine, and my 404 error has changed to a much more healthy 403. (If that causes pain, expect a blog entry on that too.)
As for why lighttpd works in such a stupid way, apparently it's by design: lighttpd bug 1427
And here's the relevant debian bug, to which I will try to remember to reply: Debian bug 445459
Incidentally, running this might be helpful:
lighttpd -tp -f /etc/lighttpd/lighttpd.conf | less
It shows you how lighttpd has understood your configuration files.
Lighttpd seems to be light on end-user documentation, and concern for ease of use. I hope I'm not making a big mistake...