February 7, 2006

Lighttpd can lighten Apache's load

Author: Robert W. Oliver II

Is your Apache Web server slowing down under the weight of streaming media content or database-driven applications? Lighttpd, sometimes pronounced "Lighty," is a lightweight HTTP server that can help alleviate Apache's load by serving static content or CGI scripts. Since Lighttpd uses fewer resources per request than Apache alone, it can generally serve most static content faster than Apache. It also benefits from an actively developed FastCGI interface that performs true load balancing, giving you all the performance benefits of compiled into Apache modules such as PHP.

One of the most beautiful things about using Lighttpd is that you can run it behind Apache via Apache's proxy module. This means you don't need to add another physical server in order to use it.

Installing Lighttpd

On most distributions, you're best off installing Lighttpd from source. This means downloading it, configuring and compiling it, then installing it. It's a fairly straightforward process. Lighttpd compiles cleanly and easily on nearly every platform I've tried it on. The essential commands for compiling and installing Lighttpd can be found on the software's download page.

If you're running Gentoo or FreeBSD, it's even easier. Under Gentoo, you can simply type emerge lighttpd to get up and running. FreeBSD has a port of Lighttpd in /usr/ports/www/lighttpd that you can install, as well via the usual ports installation method, detailed in section 4.5.2 in the FreeBSD handbook.

Once Lighttpd is installed, you'll have to build a configuration file to use it. The Lighttpd tarball comes with a sample in the doc/ folder that will fill most static-content hosting needs. While configuring all of the aspects of Lighttpd is beyond the scope of this article, it is important to pay attention to these configuration items:

# If you don't change this variable, it will try to serve document from /www/pages, which
# is probably not where your documents are. Point this to the place to serve the content
server.document-root = "/www/pages"

# Server error and access logs - make sure this path exists with a mkdir -p /var/log/lighttpd
server.errorlog = "/var/log/lighttpd/error_log"
accesslog.filename = "/var/log/lighttpd/access_log"

# bind to port (Default: 80)
server.port = 81

# bind to localhost (recommended for proxy behind Apache, otherwise comment this out for all)
server.bind = "localhost"

This is not a full listing of the configuration file, but rather a highlight of the most important parts. Notice that we've set the server port to 81. By doing this, we're making sure it doesn't clash with Apache listening on port 80. If you wanted to let Lighttpd power your entire site instead of Apache, you can set this to port 80, or comment it out to accept the default.

Setting up Apache's proxy

To let Apache take the output of Lighttpd on port 81 and map it to your Web site, you'll need to make sure the Proxy module of Apache is loaded. The following configuration examples assume you're using the Apache 2 series, but if you're running Apache 1.3 the configuration is similar in most places. For differences in the proxy module for Apache 1.3, consult the proxy module documentation.

First, make sure that Apache's proxy module is loaded, by ensuring that something resembling these lines is present in your httpd.conf file:

LoadModule proxy_module libexec/apache2/mod_proxy.so
LoadModule proxy_connect_module libexec/apache2/mod_proxy_connect.so
LoadModule proxy_http_module libexec/apache2/mod_proxy_http.so

If not, add them, or make sure that you've got the proxy module installed as per your distribution's instructions. In most cases, this module will either be there already or commented out. In the latter case, just uncomment it and restart Apache.

If you are using virtual hosting, you will want to use the following code to set up a proxy between the applicable <VirtualHost> directives. If not, putting them at the end of the httpd.conf file should do the trick:

ProxyRequests Off
ProxyPreserveHost On
ProxyPass /images http://0.0.0.0:81/
ProxyPassReverse / http://0.0.0.0:81/

In the above example, Lighttpd will serve up your images folder, leaving Apache to do the rest. You can easily set this to any folder that has static content in it and Lighttpd will serve it, instead of Apache. Another good use of Lighttpd would be to serve up multimedia files, taking the load off of Apache.

The performance boost you'll gain is dependent on many factors. If you only have Lighttpd serve up your images, it probably won't help too much. You can put all of your static content, including HTML and PDF files, images, and movies in a folder called /static and then set the ProxyPass variable to that for a slightly better boost.

Dynamic Lighty

The performance boosts you've gained so far with Lighttpd aren't phenomenal, but they can help in some heavy load situations. If you have some heavy-duty PHP scripts or a Ruby on Rails application, you might be better off letting Lighttpd handle it, as its FastCGI load-balancing is superior to Apache's. Running a Ruby on Rails application with Lighttpd's FastCGI support can yield huge performance gains.

To enable PHP behind Lighttpd, make sure that you've compiled PHP with FastCGI support. You can do this with the --enable-fastcgi configure switch. The Lighttpd documentation on PHP is quite helpful.

For Ruby on Rails, this Lighttpd configuration snippet will run your Rails application quickly and also dramatically reduce Apache's load and memory usage:

# replace path_to_app with the path to your actual Website files and Rails app
# replace rails_app_name with the folder containing the Rails app

fastcgi.server = (
".fcgi" =>
( "localhost" =>
( "socket" => "/home/path_to_app/var/lighttpd-fcgi.socket",
"bin-path" => "/home/path_to_app/rails_sites/rails_app_name/public/dispatch.fcgi",
"bin-environment" => ( "RAILS_ENV" => "production" ),
"min-procs" => 1,
"max-procs" => 1,
"idle-timeout" => 60,
"allow-x-send-file" => "enable" ) ) )

Lower server loads, happier visitors

By shifting some of the load from Apache to Lighttpd, you'll increase your Web site's performance, reduce the load on your server, and keep your visitors happier. For heavier load situations, you can put another server on the local network and have it running nothing but Lighttpd on port 80. Using Apache's proxy module, you can redirect Lighttpd's output from the local server to the front-end server with Apache by changing the ProxyPass and ProxyReverse variables to listen on the local IP.

I've found Lighttpd to be very helpful in reducing load and increasing performance, especially in serving PHP and Rails applications, and I'm confident that you will too.

Click Here!