Lighttpd

July 26, 2006 marks my first experience with lighttpd. So far I am quite impressed, and in fact the very first day I began playing with "lighty", I moved this site from Apache 2.0 to lighttpd -- after running on apache for at least 10 years.

Why you ask? Well, my interest is primarily motivated by wanting to work with ruby on rails and I have had no end of trouble trying to get that to work with Apache 2.0. I thought I might have an easier time with lighttpd.

Basic fedora install and setup

Getting it running on a clean fedora core 5 system was a simple 5 minute job as follows (note that the yum install also pulled in a package called lua, whatever that is):

yum install lighttpd
service httpd stop
chkconfig lighttpd on
service lighttpd start
chkconfig httpd off

Just this much had me serving the lighttpd test page. The RPM that yum whacked in put things in all the right places. In particular the configuration and log files are:

/etc/sysconfig/lighttpd
/etc/lighttpd/lighttpd.conf
/var/log/lighttpd

I edit the config file to have it use my document root and voila! I am serving all my stuff.

Access restriction

With lighttpd .htaccess files are no more. This is OK since it is actually more efficient (even with apache) to handle this in the main config file, and lighttpd does have the user authentication gizmos I need.

In particular, since my security needs are mild, I can just use the "plain" method with username and password as plaintext in a file outside of the document root. Then inside the lighttpd config file I add these lines to protect my photo collection:

auth.backend               = "plain"
auth.backend.plain.userfile = "/var/www/access_plain"

auth.require               = ( "/photos" =>
                               (
                                 "method"  => "basic",
                                 "realm"   => "toms photos",
                                 "require" => "user=photos"
                               )
                             )
The only thing to note in the above is that you do say method "basic" when you have a "plain" backend. Works great. Too bad you can't just put the plaintext user and password right in the config file for such non-critical applications.

Directory autoindexing

I did without this for over a year, but now I have discovered the trick. (I had always had this by default with Apache, and I think it is called "autoindex" in the apache world). As installed, my lighttpd would just complain when a URL hit an empty directory without an index file, but it can do better if you let it. There is a built in module (that you do not need to list in server.modules) called mod_dirlisting, and if you add the line:
dir-listing.activate       = "enable"
There are other options for the dir-listing module, but this has been enough for me.

Running PHP

What about running PHP? (In particular with MySQL?) Referencing a silly php file gives me a 403 forbidden error. When I turn on fastcgi in the config file I get into more hot water as it cannot find:
/usr/lib/lighttpd/mod_fastcgi.so

This is easily remedied by installing another package:

yum install lighttpd-fastcgi
yum install lighttpd-mod_mysql_vhost.i386

A side note here: I installed the mysql_vhost package since I ran across it looking for any and all lightppd related packages in my set of yum repositories. It turns out this is something I am unlikely to ever need, namely the ability to store virtual host configurations in a mysql database.

Now we have fastcgi trying to do something, namely talk to a version of PHP that is NOT fastcgi aware. Typing php -v at the command line would need to show me (cgi-fcgi), not (cli) as mine does. AHA! It would seem there is an easy answer, namely I can run a cgi aware version of php called php-cgi which tells me:

PHP 5.1.4 (cgi-fcgi) (built: May  8 2006 08:37:40)

Yep! I am now running my php test script just fine, and haven't had to compile a thing. The relevant section of the lighttpd configuration file is:

fastcgi.server = ( ".php" =>
	   ((
	      "socket" => "/tmp/php-fastcgi.socket",
	      "bin-path" => "/usr/bin/php-cgi"
	      "bin-environment" => ( 
		    "PHP_FCGI_CHILDREN" => "16",
		    "PHP_FCGI_MAX_REQUESTS" => "10000" ),
	      "bin-copy-environment" => (
		    "PATH", "SHELL", "USER" ),
	      "broken-scriptfilename" => "enable"
	     ))
	)

To make PHP_SELF and PATH_INFO work, some fiddling needs to be done to php.ini (in the fedora case, this is done already in /etc/php.d/lighttpd.ini). and in the config file via the "broken script filename" thing above.


Feedback? Questions? Drop me a line!

Ruby on Rails notes / tom@mmto.org