I am trying to install drupal on a lighttpd+php fastcgi setup on a gentoo box

drupal - 4.6.0
php - 5.0.3 (w/eaccelerator and php-cgi ebuilds)
lighttpd - 1.3.13
mysql - 4.0.22-r2

I tried googling for drupal+fastcgi and drupal+lighttpd , but didnt turn out helpful.

my lighttpd php fastcgi setup is:

fastcgi.server		= ( ".php" =>
				( "localhost" => 
				    "socket" => "/tmp/php-fastcgi.sock",
				    "bin-path" => "/usr/bin/php-cgi",
				    "bin-environment" => ( 
                                    	"PHP_FCGI_CHILDREN" => "10",
		                        "PHP_FCGI_MAX_REQUESTS" => "10000"
		                    "bin-copy-environment" => (
                  		    	"PATH", "SHELL", "USER"

my /etc/php/cgi-php5/php.ini :


after setting up the database and sites/default/settings.php with proper database values, when i try to access the index.php, the following error occurs:

Fatal error: Call to undefined function session_set_save_handler() in /.../includes/session.inc on line 9

any pointers ?



pamphile’s picture

You need to turn on session management within your php.ini.

Webmaster directory - http://01webmasters.com - soon
Debug your code - http://01debug.com

kmganesh’s picture

my Session settings in php.in are:

session.save_handler = user
session.use_cookies = 1
session.name = PHPSESSID
session.auto_start = 0
session.cookie_lifetime = 2000000
session.cookie_path = /
session.serialize_handler = php
session.gc_probability = 1
session.gc_divisor     = 100
session.gc_maxlifetime = 200000
session.bug_compat_42 = 1
session.bug_compat_warn = 1
session.referer_check =
session.entropy_length = 0
session.cache_limiter = nocache
session.cache_expire = 200000
session.use_trans_sid = 0
session.hash_function = 0
session.hash_bits_per_character = 4

does this amount to turning on session management ?


kmganesh’s picture

problem solved php-cgi in gentoo has to be compiled with --enable-session


chx’s picture

Clean URLs works with lighttpd if you add the following to common.inc, near the end, just under // Initialize $_GET['q'] prior to loading modules and invoking hook_init():

if (empty($_GET['q'])) {
  $query = strpos(request_uri(), '?');
  $request= $query ? substr(request_uri(), 0, $query) : request_uri();
  $path = substr($request, strlen(trim(dirname($_SERVER['SCRIPT_NAME']), '/'))+1);
  if ($path != '/' && $path != '/index.php') {
    $_GET['q'] = $path;

and use server.error-handler-404 = "/index.php" or wherever you put drupal.

Alas, you'll get a 404 status for every drupal page this way. There is an easy modification to connection.c so you'll get 200 always. It's not good either way. I'll stay in touch with the lighttpd developers so 1.4 will get it right.

Drupal development: making the world better, one patch at a time. | A bedroom without a teddy is like a face without a smile.

kmganesh’s picture

if i have a public ip to spare - giving a separate lighttpd instance for drupal + a global rewrite should do the trick right ?

url.rewrite-final = ( "^/(.*)$" => "/index.php?q=$1" )

also, i intend to manage file downloads via drupal


garym@teledyn.com’s picture

I have my intranet drupal set to a default home on the aggregator, and if I used the above rewrite rule, it will fail to load, complaining about

Warning: array_key_exists(): The second argument should be either an array or an object in /mnt/disk2/var/www/html/includes/module.inc on line 89

A string of these errors is followed by a block of what appears to be binary code!

The same setup will work if I load /aggregator instead of the root page. I expanded the list of re-writes to

url.rewrite-final = ( "^/(.*)$" => "/index.php?q=$1" )
url.rewrite-final = ( "^/$" => "/index.php?q=aggregator" )
url.rewrite-final = ( "^/(.*)/$" => "/index.php?q=$1" )

but still the same behaviour, and quite often (not always) a call for the root page gives a FireFox download/execute dialog, identifying the content as of type:PHP Script.

I'm also concerned with the above rewrite rules because they are not the same as the Apache rewrite rules; the original rules allow file/directory URI to pass through unchanged. Is that what rewrite-final does? If so, then something else is wrong because the above url.rewrite rule prevents running the cron.php script.

kripx’s picture

The English documentation of lighttpd's rewrite module is rather vague when it comes to explaining the difference between url.rewrite and url.rewrite-final. The French version of the same document is more explicit:

Apparently url.rewrite works in the following way: the rules are tested in order, from first to last, if a match is found the rules are retested until no valid match can be found (multiple iterations) then the request forwarded to lighttpd. Therefore the following url.rewrite statement will produce an infinite loop:

url.rewrite = (
  "abc.php" => "def.php",
  "def.php" => "abc.php" 

url.rewrite-final works in the same way as url.rewrite except that the rules are only tested once (single iteration). Therefore the following code is valid and will not produce an infinite loop:

url.rewrite-final = (
  "abc.php" => "def.php", 
  "def.php" => "abc.php" 

Lighttpd is a great webserver but the rewrite module is still not up to scratch especially when you compare it to apache's mod_rewrite. As you pointed out Gary the lighttpd rewrite module does not allow you to pass through file/directory URI when using a global rewrite rule ("^(.*)$" => "index.php?q=$1"). I've never used Drupal, but I often use the same kind of global rewrite in the webapps I develop to get SEF URLs. The only work around I've found to replace apache's RewriteCond %{REQUEST_FILENAME} !-f / -d / -l is to catch the requests going to valid files / directories:

url.rewrite-final = (
  "^/(inc|img)/(.*)$" => "/$1/$2",
  "^/.*$"                => "/index.php"

This works great for me, but it might not be so practical if you have loads of files / directories in your webroot.


codepoet’s picture

Just do this:

  if ($path != '/' && $path != '/index.php') {
    $_GET['q'] = $path;
   header("Status: 200");

Then the log shows 200 and life is good. Lighttpd shows files that exist and all else is put through Drupal.

Why isn't it doing something like this by default, anyhow? Why rely so much on a specific extension to a specific server?

Arto’s picture

We've just recently migrated from Apache to Lighty so I did some fiddling around getting this to work. I believe I came up with a near-perfect solution:

url.rewrite-final = (
  "^/system/test/(.*)$" => "/index.php?q=system/test/$1",
  "^/([^.?]*)\?(.*)$"   => "/index.php?q=$1&$2",
  "^/([^.?]*)$"         => "/index.php?q=$1"

The first line ensures that Drupal's clean URL check (when saving Settings) succeeds (Drupal makes an HTTP request for a path of the form /system/test/yLgnwqqUu5cWnvPi4Hrz.png). It's a special case that must be handled separately (read on for the reason).

The two following lines let Drupal handle any URL that doesn't contain a dot. This is significant because we can assume, fairly confidently, that addresses like /node/add are Drupal URLs, but addresses such as /themes/bluemarine/style.css are physical files. So the above configuration will work for all cases where this assumption holds true; if there are exceptions to the rule, they can be manually added to the rewrite configuration.

Adrian Freed’s picture

for searches containing dots?

drupal puts the search string in the path. I already notice issues relating to this when searching for "os/x" because of the slash.

UncleD’s picture

After many woes I made this one work too. For readers just tuning it, this must be applied to lighttpd.conf's file, then you must restart lighttpd for it to take effect.

Also, where it says ^/system - you may need to modify that to specify the actual document root location of your drupal. For example, if server.document-root = "/home/websites/uncled.com"
but drupal is located at /home/websites/uncled.com/drupal then i need to specify the following:
url.rewrite-final = (
"/drupal/system/test/(.*)$" => "/drupal/index.php?q=system/test/$1",
"/drupal/([^.?]*)\?(.*)$" => "/drupal/index.php?q=$1&$2",
"/drupal/([^.?]*)$" => "/drupal/index.php?q=$1"

UncleD’s picture

Adding this to lightthpd.conf brings us even closer to perfection than the previous options:
url.rewrite-final = (
"^/system/test/(.*)$" => "/index.php?q=system/test/$1",
"^/([^.?]*)\?(.*)$" => "/index.php?q=$1&$2",
"^/([^.?]*)$" => "/index.php?q=$1"
"^/search/node/(.*)$" => "/index.php?q=search/node/$1"

That will handle searches for items that contain .'s in them
for example searching for fun.jpg would previously result in a 404, now itll work fine.

chastell’s picture

The next-to-last line benefits immensely from a comma at the end:

url.rewrite-final = (
  "^/system/test/(.*)$" => "/index.php?q=system/test/$1",
  "^/([^.?]*)\?(.*)$" => "/index.php?q=$1&$2",
  "^/([^.?]*)$" => "/index.php?q=$1",
  "^/search/node/(.*)$" => "/index.php?q=search/node/$1"

Seriously, though – thanks a lot for the above! Works like a charm.

joevstewart’s picture

I had a problem with node/feed and rss.xml.

Two problems.

1. The url-rewrite-final doesn't match rss.xml on purpose. Had to add:

   "^/rss.xml$" => "/index.php?q=rss.xml",

2. There was no alias for node/feed to point to rss.xml. This was installed in 4.7 beta2,

Now feed urls for both node/feed and rss.xml display correctly in lighttpd and drupal 4.7.

S2eve’s picture

wow thanks so much!

magico’s picture

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

Because i18n adds the language before the link, we need to be flexible for the 3 specific rewrite rules.

pbd’s picture

And of course if you are using private files you need to add:

 "^/system/files/(.*)$" => "/index.php?q=system/files/$1",

or you get 404 errors and can't see any of your images.

jslag’s picture

Using 4.7.0 RC 3, I needed to change the first rewrite line to:

"^/system/test-clean-url/(.*)$" => "/index.php?q=system/test-clean-url/$1",

adrianmak’s picture

I'm using lighttpd 1.4.11 , php 5.1.2 and drupal 4.7

What are the final rewrite rules work perfectly ?

magico’s picture


But there is still the problem, with "searchs" that include a dot
Fernando Silva
Openquest - Sistemas de Informação, Lda