Running Drupal using Lighttpd and PostgreSQL

This article explains how to get the content management system Drupal 6 running on the Lighttpd 1.4 web server. PostgreSQL 8 is used as the database for Drupal. The required configuration of PHP 5 is also covered, since it can cause a few headaches. Configuration of Lighttpd is done so that Drupal runs in normal CGI or FastCGI mode. All shown command line calls work on Debian Linux but should be easily portable to other distributions.

Prerequisites

In order to ensure I have the latest versions, I usually prefer to compile programs myself. In the case of PHP, this is also necessary to make sure the needed compilation options have been set. You can get all programs used in this article here:
PostgreSQL: http://www.postgresql.org
PHP: http://www.php.net
Lighttpd: http://www.lighttpd.net
Drupal: http://drupal.org
phpPgAdmin (optional): http://phppgadmin.sourceforge.net

PostgreSQL

Basic installation of PostgreSQL is easy and follows the short version of the PostgreSQL manual. Download the latest release, compile and install it:

./configure
make
make install

Add a Linux user to run the server, set up your database's data directory and start the server. The following commands will create a user postgres and initialise the database in the directory /usr/local/pgsql/data.

adduser postgres
mkdir /usr/local/pgsql/data
chown postgres /usr/local/pgsql/data
su postgres
/usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data
/usr/local/pgsql/bin/postgres -D /usr/local/pgsql/data >logfile 2>&1 &

Now you can create a database user and a database for your Drupal installation:

createuser --pwprompt --encrypted --no-adduser --no-createdb username
createdb --encoding=UNICODE --owner=username databasename

PHP

PHP can be a bit tricky to configure if you want to use it with PostgreSQL. The biggest catch is that PHP has to be compiled with PostgreSQL support. If you run the Drupal installation script without PostgreSQL support, it will just tell you that you do not have a supported database, even though you have a perfectly fine PostgreSQL DB running.

To find out whether your PHP installation already has PostgreSQL support, you could get phpPgAdmin. phpPgAdmin is a web-based administration tool, written in PHP, for PostgreSQL. Simply run it on your web server and it will tell you if your PHP installation supports PostgreSQL or not. Of course this requires a working web server, so you might have to skip to the Lighttpd installation further down the page or compile PHP anyway.

To install PHP with PostgreSQL support, download the PHP source code and follow the usual configure, make, make install chain. This time you have to pass a few parameters to the configure script, though. You might want to remove all existing PHP installation first. I had to remove all PHP packages and delete remaining PHP installations manually in order to get it to work. Enabling PostgreSQL support requires the --with-pgsql= parameter pointing to your PostgreSQL installation (e.g. /usr/local/pgsql) when running the configure script. This example also has a few useful additional configure-options. For example it includes mbstring and GD library support; both of which are used by Drupal. Some options like --enable-memory-limit are redundant in newer PHP versions, yet older versions still require them. FastCGI (--enable-fastcgi) has been included in case you want to switch to fast-CGI later on. It is purely optional though.

./configure --with-pgsql=/usr/local/pgsql --enable-force-cgi-redirect --enable-memory-limit --enable-discard-path --enable-sockets --enable-mbstring --enable-mbstr-enc-trans --with-gd --enable-fastcgi
make
make test
make install

Make sure the output of the configure script mentions successful PostgreSQL support activation (something along the lines of PostgreSQL support ... yes).

Change your php.ini file to satisfy the requirements of Drupal (according to their system requirements):

register_globals = off
session.save_handler = user
error_reporting = E_ALL
safe_mode = off
session.cache_limiter = nocache

To verify your installation, run phpPgAdmin or wait until Drupal will be ready to run.

Lighttpd

Installation is the easy part in setting up Lighttpd for Drupal. Download it and follow the usual procedure:

./configure
make
make install

As Drupal officially only supports Apache and IIS, you have some configuration to do. Compiling a list of working configuration settings can be cumbersome, as they are scattered across various comments and discussions on different sites. The following settings belong in your Lighttpd configuration file (e.g. /etc/lighttpd/lighttpd.conf).

Activate required mods by inserting them in server.modules (or uncomment their lines if they are already there). You need: mod_rewrite, mod_access and mod_cgi.

In order to run CGI scripts, you have to tell Lighttpd which program to use for which type of script. In our case this is PHP. Change it to wherever your php-cgi executable is located.

cgi.assign = (
  ".php" => "/usr/local/bin/php-cgi"
)

Update: Alternatively you can run Drupal in FastCGI-mode. FastCGI uses more system memory when nobody currently accesses the site but improves response times. Activate module mod_fastcgi in the Lighttpd configuration. Replace the above cgi.assign with an appropriate fastcgi.server setting. See the Lighttpd documentation on mod_fastcgi for help. For example:

fastcgi.server = (".php" =>
  ((
    "min-procs" => 1,
    "max-procs" => 3,
    "socket" => "/tmp/php-fastcgi.socket",
    "bin-path" => "/usr/local/bin/php-cgi",
    "idle-timeout" => 60,
    "bin-environment" => (
      "PHP_FCGI_CHILDREN" => "5",
      "PHP_FCGI_MAX_REQUESTS" => "10000"
    )
  ))
)

Several rewrite rules have to be created, so that Lighttpd forwards requests to the appropriate Drupal script. The following rules are from a discussion at http://drupal.org/node/20766. They work for me. They assume that Drupal is installed in your servers root directory. If it is not, you have to prefix the subdirectory to the rules.

url.rewrite-once = (
  "/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"
)

Also set the 404-handler to Drupal's index.php:

server.error-handler-404 = "/index.php"

In order to restrict access to some parts of Drupal, the directives of the original .htaccess-file have to be replicated. Lighttpd does not know .htaccess-files but it can restrict access via the url.access-deny option. Add (or change) these lines to restrict access to files mentioned in the original .htaccess. Take note that this is an attempt to restrict access to the same files that are given in the .htaccess-file. Unfortunately Apache's and Lighttpd's method of restricting access differ. So it is (to my knowledge) not possible to express all restrictions of the .htaccess-file in Lighttpd's configuration.

url.access-deny = (
  "~", ".engine", ".inc", ".info", ".install", ".module", ".profile",
  ".po", ".sh", ".sql", ".theme", ".tpl", ".tpl.php", ".xtmpl",
  "code-style.pl", "Repository", "Root", "Tag", "Template"
)

On a new installation of Lighttpd, you probably have to adjust several general configuration options, too. They are not covered here but you can find a lot of information in Lighttpd's documentation. Don't forget to start (or restart) Lighttpd after changing its configuration.

Drupal

With all prerequisites present, Drupal can finally be installed. Extract it into your web server's root or the directory you want it to reside. If this is not your server's root, you have to adjust the rewrite rules accordingly. Don't forget to change ownership of Drupal files to the user that runs Lighttpd. Execute the following command in your Drupal directory:

chown -R webuser:webgroup *

When you direct your browser to the newly extracted Drupal, the installation script should start and guide you through the rest of the process.

Conclusion

After going through all of the above steps, you should have working installations of PostgreSQL, PHP, Lighttpd and Drupal. Feel free to comment on any missing information or flaws you find.