Thursday, April 16, 2009

Ubuntu 9.04: Installing Lighttpd 1.5 from source with PHP + mod_cache

To install PHP:
sudo apt-get install php5-cgi

Installing Lighttpd 1.5
The latest version I could find on their site:


This is the patched version of lighttpd with mod_cache, extract this to a folder

tar zxvf lighttpd-1.5.#######.gz
cd lighttpd-1.5.0.cache

We need to install some required libraries first

sudo apt-get install libssl-dev zlib1g-dev libbz2-dev libattr1-dev libpcre3-dev libmysqlclient15-dev libfam-dev libldap2-dev libfcgi-dev libgdbm-dev libmemcache-dev liblua5.1-0-dev pkg-config uuid-dev libsqlite3-dev libxml2-dev libkrb5-dev libglib2.0-dev libaio-dev libfam0 memcached

type ./configure --help to see configuration options

This is what I used
./configure --program-prefix= --prefix=/usr --exec-prefix=/usr --bindir=/usr/bin --sbindir=/usr/sbin --sysconfdir=/etc --datadir=/usr/share --includedir=/usr/include --libdir=/usr/lib --libexecdir=/usr/libexec --localstatedir=/var --sharedstatedir=/usr/com --mandir=/usr/share/man --infodir=/usr/share/info --with-openssl --with-memcache --with-gdbm


sudo make install

after installing you should be able to type
lighttpd -V

and see some nice output from lighttpd

you can also type spawn-fcgi to make sure that installed as well

type sudo su

copy the sample config file
mkdir /etc/lighttpd
cp doc/lighttpd.conf /etc/lighttpd/

log folder
mkdir /var/log/lighttpd

we need to create a startup file in the /etc/init.d folder
Go here to download the startup script
create a file called lighttpd in the /etc/init.d/ folder and then
chmod a+x /etc/init.d/lighttpd

Create a user to run lighttpd: if you have installed lighttpd 1.4 from apt or apache you can just use the www-data user again
adduser -m -d /var/www -s /sbin/nologin lighttpd

Modify the lighttpd file from /etc/init.d/ to match the user you want to run it as

chown www-data:www-data /var/log/lighttpd

then type
update-rc.d lighttpd defaults

Edit the lighttpd.conf file to enable php fastcgi

Make sure following modules are loaded:
server.modules += ( "mod_cache" "mod_proxy_core", "mod_proxy_backend_fastcgi" )

You can also enable other modules that you need, mod_cache has to be enable first!
cache.bases = ("/var/cache/lighttpd")
cache.enable = "enable" = "enable"
cache.debug = "enable"
cache.dynamic-mode = "enable"
server.document-root = "/var/www/"
server.errorlog = "/var/log/lighttpd/error.log"
server.event-handler = "linux-sysepoll" = "gthread-aio"
accesslog.filename = "/var/log/lighttpd/access.log"
compress.cache-dir = "/tmp/lighttpd/cache/compress/"
compress.filetype = ("text/plain", "text/html")
#### status module
status.status-url = "/server-status"
status.statistics-url = "/server-statistics"

cache.bases = ("/var/cache/lighttpd")
cache.enable = "enable" = "enable"
cache.debug = "enable"
cache.dynamic-mode = "enable"
cache.refresh-pattern = (
"/$" => "5 update-on-refresh no-expire-header", # update homepage every 5 minutes and on refresh requests without setting expire headers
"\.(?i)(flv)$" => "0 fetchall-for-range-request flv-streaming", # to work with mod_flv_streaming for flv files
"\.(?i)(js|css|xml)$" => "240", # update js/css/xml every 4 hours and on refresh requests
"\.(?i)(htm|html|shtml)$" => "30", # update html/htm/shtml every 30 minutes and on refresh requests
"\.(?i)(jpg|bmp|jpeg|gif|png)$" => "2880", # update graphics files every 2 days
"\.(?i)(rar|zip|wmv|avi|mp3|ape|rm|mpeg|mpg|wma|asf|rmvb|flv)$" => "0 fetchall-for-range-request", # cache media file forever
".(?i)php$" => "5", # update php request every 5 minutes
"." => "30 update-on-refresh" # default to update every 30 minutes and on refresh requests

Make sure /var/cache/lighttpd is writeable by lighttpd and it exists.

Configure fastcgi PGP module by appending following configuration directives:

$HTTP["url"] =~ "\.php$" {
proxy-core.balancer = "round-robin"
proxy-core.allow-x-sendfile = "enable"
# proxy-core.check-local = "enable"
proxy-core.protocol = "fastcgi"
proxy-core.backends = ( "unix:/tmp/php-fastcgi.sock" )
proxy-core.max-pool-size = 16
proxy-core.worked-with-modcache = "enable"

Make sure to leave the # in front of proxy-core.check-local = "enable" otherwise lighttpd won't start, don't know why.

Also don't forget to add proxy-core.worked-with-modcache = "enable" otherwise mod_cache won't do anything.

Save the config file and start lighttpd

sudo /etc/init.d/lighttpd start

If everything goes well you should see something like this
* Starting lighttpd [ OK ]
* Starting spawn-fcgi spawn-fcgi.c.206: child spawned successfully: PID: 15245
[ OK ]

inside the /var/www folder create index.php file and add something to it

test by browsing http://localhost/index.php
You should see php configuration options here

How to uninstall
go back to the lighttpd source
sudo make uninstall


Saturday, April 11, 2009

Traffic Shaping with Lighttpd + PHP

Here's how I manage traffic on my web site that's served over a basic cable connection. The site has a forum and an area for register members to download stuff from. Having a very limited upload capacity I have to make sure members don't suck everything and make the forum unresponsive.

So here's how my lighttpd.conf file is setup:

# this limits the amount of connection a user can make to the server
evasive.max-conns-per-ip = 10

# then on my site configuration I use a combination of connection.kbytes-per-secon and evasive.max-conns-per-ip to throttle user connections to the download script
$HTTP["host"] =~ "sitegeisha\.dyndns\.dk" {
connection.kbytes-per-second = 64
$HTTP["url"] =~ "dl\.php" {
connection.kbytes-per-second = 32
evasive.max-conns-per-ip = 3

This configuration allows me to limit the number of simultaneous downloads they can make, if they go over 3 they get a 403 error message.