Using lighttpd with apache to serve static content
There’s a decent performence boost to be obtained by coupling apache with lighttpd, a lightweight (hence the name) web server with great features and a ridiculously small footprint.
In this example…. we’re configuring lighttpd as our forward-facing (port 80) web server, which will use mod_proxy (proxy module) to send any dynamic requests back to apache listening on port 8080, while lighttpd takes care of any and all static content. I won’t go into the details of *installing* lighttpd or apache as this is beyond the scope of this article.
First of all…. ports.
In the Apache config (/etc/apache2/ports.conf if you’re using Debian, or /etc/httpd/conf/httpd.conf if you’re using RedHat or a derivative, these are just the defaul install locations) you want to find the following line:
Listen 80
And change it to:
Listen 8080
That’s it for the apache config! By default, lighttpd should already be listening on port 80 so we don’t need to change that.
In lighttpd.conf (wherever your distro of choice chooses to place this file), find the server.modules section, and uncomment (or add, if it’s not there already) the following line:
"mod_proxy",
Now, scoot down to the bottom of the file, and we’ll set up the proxy:
$HTTP["url"] !~ “(?i)\.(js|css|gif|jpg|png|ico|txt|swf|mp3|pdf|ps|wav|flv|zip|rar|gz|tar)$” {
proxy.server = ( “” => (
( “host” => “your-server-ip-here”, “port” => 8080 )
))
}
Obviously substitute “your-server-ip-here” with the IP address of your web server. This is very important, because if you use any virtual hosts, they won’t like it if you just set host to 127.0.0.1 (or at least they didn’t in my config).
Which brings me to the next point…. virtual hosts. If you are serving several domains from the same location and use several different virtual hosts, you will need a virtual host definition for each because lighttpd simply needs to know where to look for your static content! This worked for me (for this site):
$HTTP["host"] =~ “(^|\.)richardwalker\.com\.au$” {
server.document-root = “/opt/web/richardwalker.com.au”
}
That’s it….. thats a virtual host definition in lighttpd. There are several more options but for the purposes of this demonstation (and of this site), that worked a treat.
All that’s needed now is to stop both apache and lighttpd, then start them up again.
You might wonder why this approach is beneficial….. it is possible to set up apache to use persistent connections, which means it fetches all the content (the root page, the CSS, the images, etc) all in the one connection. This can be troublesome for sites with huge amounts of traffic, as instead of just dropping off when the job is done, persistent connections hang around for a predetermined length of time. Large amounts of concurrent traffic can quickly turn into a large number of persistent connections.
Alternatively, if you leave persistent connections off, you get a connection made to the web server for each item in the HTML that needs fetching…. the root HTML itself, a CSS file or two, a JS include, all the images……. for each one of those, Apache will fire up a process, load its modules etc, fetch the item, and drop off. This can result in very large chunks from memory being eaten up all at once in bursts, which can slow things down considerably.
There are of course several schools of thought on this sort of thing, and everyone has an opinion about which is better…. for me, the approach outlined above works perfectly. My lighttpd access log has hits for all the static items, and my apache log has only the single hit, the initial GET request for the HTML itself. Which is exactly the way it should be.