vps

Installing lighttpd on CentOS 4

updated Oct 23, 2007

I recently decided to switch from Apache to lighttpd because Apache along with mod_php was using up a lot of memory and Lighttpd apparently has a lighter memory footprint. The difference is significant - with Apache, I was using up nearly all of my 256MB whereas with Lighttpd, I'm using only 132MB and I think with some tuning, I'll be able to get it lower.

In order to install lighttpd with yum, you need to include the RPMForge repository. Instructions on how to do this are here.

For some reason the RPMForge repository only showed version 1.3.16 for me, so I used RPMs, which can be grabbed here. Make sure that you grab the one that matches your distro and system architecture. If you use php, you'll want to install the fastcgi rpm as well. To install, I did:


$ wget http://dag.wieers.com/rpm/packages/lighttpd/lighttpd-1.4.18-1.el4.rf.x86_64.rpm
$ wget http://dag.wieers.com/rpm/packages/lighttpd/lighttpd-fastcgi-1.4.18-1.el4.rf.x86_64.rpm
$ rpm -Uvh lighttpd-1.4.18-1.el4.rf.x86_64.rpm
$ rpm -Uvh lighttpd-fastcgi-1.4.18-1.el4.rf.x86_64.rpm

You should then be able to start up the daemon with:


$ service lighttpd start

The configuration file is /etc/lighttpd/lighttpd.conf. In it, you should set your web root with the server.document-root directive.

Getting lighttpd to serve PHP files

Make sure that you installed lighttpd-fastcgi above. Make sure that the following line exists in /etc/php.ini though it should have the right setting by default:

cgi.fix-pathinfo = 1

Make sure mod_fastcgi is uncommented (and thus loaded) in server.modules in your lighttpd.conf file:

Server.modules = (
	mod_fastcgi,
			)

Then make sure the fast.server section is uncommented and looks like as follows:

fastcgi.server = ( ".php" => (( 
                     "bin-path" => "/path/to/php-cgi",
                     "socket" => "/tmp/php.socket"
                 )))

My bin-path was /usr/bin/php-cgi. If you're unsure, you can issue the following command:

$ whereis php-cgi

Then restart the lighttpd daemon with:

$ service lighttpd restart

And you should be able to serve php files.

Virtual Hosts

Virtual hosting can be done in a few different ways: using conditionals, simple-vhosts or a combination of conditionals and simple-vhosts. As I understand it, simple-vhosts are used for where all your virtual hosts (domains, subdomains or sites) have the same structure within the web root and conditionals are used for exceptions.

Since I have a relatively small number of sites, I decided to go the route of using conditionals. For documentation on this, take a look at this wiki article.

In lighttpd.conf, I used the following as an example:

$HTTP[host] == domain.com {
server.document-root = /path/to/document/root/for/domain.com
}
$HTTP[host] == domain2.com {
server.document-root = /path/to/document/root/for/domain2.com
}

Using a combination of conditionals and simple-vhosts can save you some typing. For example:

$HTTP["host"] == "subdomain1.example.org" {
 #conditional
}
else $HTTP["host"] == "subdomain2.example.org" {
 #conditional
}
else $HTTP["host"] =~ "^." {
 # simple vhost stuff here
}

Redirecting domain.com to www.domain.com

If you'd like to redirect requests made to domain.com to www.domain.com you can't do it using an .htaccess file because lighttpd doesn't support them. You can, however enable mod_redirect in lighttpd.conf (uncomment it at the top of the file) and use something like the following:


$HTTP["host"] !~ "^(www|mail|webmail|208)" {
  $HTTP["host"] =~ "^(.*)" {
    url.redirect = ("^/(.*)" => "http://www.%1/$1")
  }
}

What that does is redirects any http requests that do not start with www, mail, webmail or 208 to the same url except beginning with "http://www." I have "208" in there as well because if I type in my server IP address, I don't want it to be redirected.

You can also include this within a virtual host so that this conditional affects only certain domains.

Drupal Clean URLs

Using mod_rewrite seemed to be the easiest way to enable clean URLs in drupal. You will want to enable mod_rewrite (uncomment it out at the top of your lighttpd.conf) and then use the following code:


url.rewrite-final = (
  "/rss.xml$" => "/index.php?q=rss.xml",
  "^/([^.?]*)\?(.*)$" => "/index.php?q=$1&$2",
  "^/search/(.*)$" => "/index.php?q=search/$1",
  "^/([^.?]*)$" => "/index.php?q=$1",
  "^/([^.?]*\.html)$" => "/index.php?q=$1",
  "^/([^.?]*\.htm)$" => "/index.php?q=$1"
)

I have multiple sites on my server and only a portion of them are drupal sites, so I put those rewrite rules into a vhost:


$HTTP["host"] == "www.mydomain.com" {
  server.document-root = "/var/www/html/drupal"
  url.rewrite-final = (
    "/rss.xml$" => "/index.php?q=rss.xml",
    "^/([^.?]*)\?(.*)$" => "/index.php?q=$1&$2",
    "^/search/(.*)$" => "/index.php?q=search/$1",
    "^/([^.?]*)$" => "/index.php?q=$1",
    "^/([^.?]*\.html)$" => "/index.php?q=$1",
    "^/([^.?]*\.htm)$" => "/index.php?q=$1"
  )
}

You may be puzzled by why the server.document-root is set to something that looks rather generic, but that is because I use drupal's multisite feature, so all my drupal sites use that same document root.

Wordpress permalinks

Wordpress permalinks can be enabled in a very similar way as with drupal. Mod_rewrite should be enabled, and then the following code used:


url.rewrite-final = (
  "^/(wp-.+).*/?" => "$0",
  "^/(sitemap.xml)" => "$0",
  "^/(xmlrpc.php)" => "$0",
  "^/(.+)/?$" => "/index.php/$1"
)

And for a specific virtual host:


$HTTP["host"] == "www.wordpress_site.com" {
  server.document-root = "/var/www/html/domains/wordpress_site"
  url.rewrite-final = (
    "^/(wp-.+).*/?" => "$0",
    "^/(sitemap.xml)" => "$0",
    "^/(xmlrpc.php)" => "$0",
    "^/(.+)/?$" => "/index.php/$1"
  )
}

Odani Interactive is an Internet services company located in New York City. Our core competencies are online marketing (in particular direct response advertising) and web development.