Drupal on lighttpd with clean urls made easy

Apache is and will be one of the best/popular webservers out there for years for most websites, but nowadays, when it comes to scalability, load, performance and speed, my first choice of webserver is lighttpd, also called lighty. It took me some months to create the perfect configuration for a Drupal site with a lot modules but I think I finally found it. My setup is used for Drupal 5.3 (and for the first time on a new site called CarChannel, cf http://realize.be/carchannel), but will be more or less the same for the upcoming 6.x release in a few months. And even if you keep using apache, the rest of this article still is interesting to gain more speed for your Drupal setup with more caching tips!

Lighttpd and clean URL's - http://www.lighttpd.net/
I was very impressed with a previous project we launched at work using lighttpd instead of apache. The load on the machine constantly kept under 0.40 having more then 1 million hits per day. Time to check if Drupal would run also as smooth on this server. Lighttpd doesn't support mod_rewrite like Apache does, but after lots of googling, I finally found the solution which also enables clean urls and keeps everything running as it should. The answer is LUA and mod_magnet. No more exotic rewrite rules in your lighttpd.conf which always caused problems at some point. I'm not going to explain it here again for you, all credits go to other authors for creating this configuration. Read following pages to make your sites fly

When all is done, your Drupal setup works with clean urls and yes imagecache works fine! An excerpt of my local lighttpd.conf configuration is underneath:

server.modules = (
   "mod_access",
   "mod_fastcgi",
   "mod_magnet",
   "mod_simple_vhost",
)

fastcgi.server =
   ( ".php" =>
     ( "localhost" =>
       (
         "socket" => "/var/run/lighttpd/php-fastcgi.socket",
         "bin-path" => "/usr/bin/php-cgi"
       )
     )
   )

url.access-deny = ( "~", ".inc", ".engine", ".install", ".module", ".sh", "sql", ".theme", ".tpl.php", ".xtmpl", "Entries", "Repository", "Root" )

$HTTP["host"] =~ "(^|\.)connector$" {
  index-file.names = ( "index.php" )
  simple-vhost.server-root   = "/home/"
  simple-vhost.default-host  = "projects"
  simple-vhost.document-root = "connector"
  magnet.attract-physical-path-to = ( "/etc/lighttpd/drupal.lua" )
  server.errorlog             = "/var/log/lighttpd/connector-error.log"
  accesslog.filename             = "/var/log/lighttpd/connector-access.log"
}

XCache - http://xcache.lighttpd.net
XCache is a fast, stable PHP opcode cacher that has been tested and is now running on production servers under high load. It is tested (on linux) and supported on all of the latest PHP cvs branches such as PHP_4_3 PHP_4_4 PHP_5_0 PHP_5_1 PHP_5_2 HEAD(6.x). ThreadSafe/Windows is also supported. It overcomes a lot of problems that has been with other competing opcachers such as being able to be used with new PHP versions. Does the same thing like APC and I really prefer this one, because running APC with PHP5 on lighty was a nightmare. XCache seems to do the job well without segfaulting every hour.

APC - http://be.php.net/apc
The Alternative PHP Cache (APC) is a free and open opcode cache for PHP. It was conceived of to provide a free, open, and robust framework for caching and optimizing PHP intermediate code. This framework will keep your scripts in a compiled form in memory, so every script doesn't have to be interpreted with every call you make to your website. The PECL package is not bundled in the PHP package itself, but is easy installable by just typing 'pecl install apc'. After that just add 'extension=apc.so' to your php.ini and restart your webserver. Warning: running with PHP5 is unstable, PHP4 runs perfect.

Both opcache codes optimize the speed results sometimes by 5!

MySQL Query Cache - http://dev.mysql.com/doc/refman/5.0/en/query-cache.html
The query cache stores the text of a SELECT statement together with the corresponding result that was sent to the client. If an identical statement is received later, the server retrieves the results from the query cache rather than parsing and executing the statement again. No further explanation is needed I guess.

Drupal settings
Drupal comes with it's own caching and speed tricks. Enable normal page caching for anonymous users which results in less database queries and faster page loads. Logged-in visitors don't benefit from the caching, but read on if you also want to have a decent caching for those users! You can also aggregate css files when your site is production. Drupal 6 also supports this feature for all javascript files, great! Drupal core also ships the throttle module which handles site congestion. I've personally never used it, but it's worth mentioning it.

Module: Block Cache - http://drupal.org/project/blockcache
"This module creates a cached version of each block. Block caching happens separately from page caching and so it will work for logged-in users whether or not page caching is enabled for the site." This is a huge advantage because it can reduce complex queries or calculations needed for some blocks. The interface also permits you to set a cache expiry time and whether it's a page and/or user specific content block. Highly recommended! Note: block cache is in core starting from Drupal 6.x!

Module: Advanced Cache - http://drupal.org/project/advcache
"The advanced caching module is mostly a set of patches and a supporting module to bring caching to Drupal core in places where it is needed yet currently unavailable. These include caching nodes, comments, taxonomy (terms, trees, vocabularies and terms-per-node), path aliases, and search results." The only small downside in my opinion is that when a new release of Drupal core is out, you really need to re-apply these patches and sometimes need to patch files manually. At the time of this writing, an official Drupal 5.3 release isn't out there, but the patches are allready available on http://drupal.org/node/184522. Only use if if you think it's really worth it.

Module: Memcache - http://drupal.org/project/memcache
An API for using Memcached and the PECL Memcache library with Drupal. Instead of storing the data into the database, cached data is available in memory. At this time, it seems to be broken with the 5.3 release. Tests with 5.2 work fine, so let's hope a new release is out soon, because together with all previous settings, the boost performance is enormous!

That's it. After reading this, you should be able to make your new site fly, happy tuning! When I find some time, I'll try and generate some benchmark reports, but I'm pretty sure you will feel the difference yourself. You can also read http://drupal.org/node/2601 on drupal.org which handles the same topic, interesting for all you sysadmins out there.

AttachmentSize
drupal.lua1.09 KB

Comments

Submitted by Chris Muktar on November 10, 2008 - 20:24

What have been your experiences of lighthttpd since writing this article? Have you migrated a busy site from apache to lighthttpd and found any quantifiable advantage?

Submitted by swentel on November 11, 2008 - 12:38

@ Chris
We have now one server which only runs lighttpd. It's used for sites who suffer from high peaks now and then because of periodical campaines on the internet/tv etc. Moving it to lighttpd was a good option here - we could install a second webserver though with a load balancer and apache, but as long we can avoid that, I don't see any reason todo so. So yeah, less memory, more requests can be handled and I sleep better at night :)

Submitted by drupal malaysia on October 1, 2009 - 08:55

Hi ..thanks for this. On multisites environment, I created a subdirectory which is symbolicly linked to another folder.

so say I have http://example.com/drupal, http://example.com/drupal2, http://example.com/drupal3, I can't get it to work for all as lua variant needs one script per drupal prefix, because i have to set the prefix in the lua script!

so when i use prefix "drupal" only the first one works.

got a way around this?

Submitted by iddaa on October 18, 2009 - 05:16

What have been your experiences of lighthttpd since writing this article? Have you migrated a busy site from apache to lighthttpd and found any quantifiable advantage?

Submitted by Yonas on July 17, 2011 - 06:03

It's worth noting that the prefix will likely need to be changed before clean urls works.

Normally I have to set the prefix as so:

...
...
-- prefix without the trailing slash
local prefix = ''

You are here