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"
  )
}

Comments

Submitted by gabriel (not verified) on December 28, 2007 - 10:48.

hi! you have an excellent tutorial, and I managed to install Lighty on my Centos 4.5 but I couldnt get PHP to run. This happens:

[root@serber ~]# whereis php-cgi
php-cgi:

So when I try to restart this happens:
[root@serber ~]# service lighttpd restart
Stopping lighttpd: [FAILED]
Starting lighttpd: [ OK ]

Anyway, I attached my lighttpd.conf below. Hope you can help!

############ Options you really have to take care of ####################

## modules to load
# at least mod_access and mod_accesslog should be loaded
# all other module should only be loaded if really neccesary
# - saves some time
# - saves memory
server.modules = (
# "mod_rewrite",
# "mod_redirect",
# "mod_alias",
"mod_access",
# "mod_cml",
# "mod_trigger_b4_dl",
# "mod_auth",
# "mod_status",
# "mod_setenv",
"mod_fastcgi",
# "mod_proxy",
# "mod_simple_vhost",
# "mod_evhost",
# "mod_userdir",
# "mod_cgi",
# "mod_compress",
# "mod_ssi",
# "mod_usertrack",
# "mod_expire",
# "mod_secdownload",
# "mod_rrdtool",
"mod_accesslog" )

## a static document-root, for virtual-hosting take look at the
## server.virtual-* options
server.document-root = "/var/www/"

## where to send error-messages to
server.errorlog = "/var/log/lighttpd/error.log"

# files to check for if .../ is requested
index-file.names = ( "index.php", "index.html",
"index.htm", "default.htm" )

## set the event-handler (read the performance section in the manual)
# server.event-handler = "freebsd-kqueue" # needed on OS X

# mimetype mapping
mimetype.assign = (
".rpm" => "application/x-rpm",
".pdf" => "application/pdf",
".sig" => "application/pgp-signature",
".spl" => "application/futuresplash",
".class" => "application/octet-stream",
".ps" => "application/postscript",
".torrent" => "application/x-bittorrent",
".dvi" => "application/x-dvi",
".gz" => "application/x-gzip",
".pac" => "application/x-ns-proxy-autoconfig",
".swf" => "application/x-shockwave-flash",
".tar.gz" => "application/x-tgz",
".tgz" => "application/x-tgz",
".tar" => "application/x-tar",
".zip" => "application/zip",
".mp3" => "audio/mpeg",
".m3u" => "audio/x-mpegurl",
".wma" => "audio/x-ms-wma",
".wax" => "audio/x-ms-wax",
".ogg" => "application/ogg",
".wav" => "audio/x-wav",
".gif" => "image/gif",
".jpg" => "image/jpeg",
".jpeg" => "image/jpeg",
".png" => "image/png",
".xbm" => "image/x-xbitmap",
".xpm" => "image/x-xpixmap",
".xwd" => "image/x-xwindowdump",
".css" => "text/css",
".html" => "text/html",
".htm" => "text/html",
".js" => "text/javascript",
".asc" => "text/plain",
".c" => "text/plain",
".cpp" => "text/plain",
".log" => "text/plain",
".conf" => "text/plain",
".text" => "text/plain",
".txt" => "text/plain",
".dtd" => "text/xml",
".xml" => "text/xml",
".mpeg" => "video/mpeg",
".mpg" => "video/mpeg",
".mov" => "video/quicktime",
".qt" => "video/quicktime",
".avi" => "video/x-msvideo",
".asf" => "video/x-ms-asf",
".asx" => "video/x-ms-asf",
".wmv" => "video/x-ms-wmv",
".bz2" => "application/x-bzip",
".tbz" => "application/x-bzip-compressed-tar",
".tar.bz2" => "application/x-bzip-compressed-tar",
# default mime type
"" => "application/octet-stream",
)

# Use the "Content-Type" extended attribute to obtain mime type if possible
#mimetype.use-xattr = "enable"

## send a different Server: header
## be nice and keep it at lighttpd
# server.tag = "lighttpd"

#### accesslog module
accesslog.filename = "/var/log/lighttpd/access.log"

## deny access the file-extensions
#
# ~ is for backupfiles from vi, emacs, joe, ...
# .inc is often used for code includes which should in general not be part
# of the document-root
url.access-deny = ( "~", ".inc" )

$HTTP["url"] =~ "\.pdf$" {
server.range-requests = "disable"
}

##
# which extensions should not be handle via static-file transfer
#
# .php, .pl, .fcgi are most often handled by mod_fastcgi or mod_cgi
static-file.exclude-extensions = ( ".php", ".pl", ".fcgi" )

######### Options that are good to be but not neccesary to be changed #######

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

## bind to localhost (default: all interfaces)
#server.bind = "127.0.0.1"

## error-handler for status 404
#server.error-handler-404 = "/error-handler.html"
#server.error-handler-404 = "/error-handler.php"

## to help the rc.scripts
server.pid-file = "/var/run/lighttpd.pid"

###### virtual hosts
##
## If you want name-based virtual hosting add the next three settings and load
## mod_simple_vhost
##
## document-root =
## virtual-server-root + virtual-server-default-host + virtual-server-docroot
## or
## virtual-server-root + http-host + virtual-server-docroot
##
#simple-vhost.server-root = "/srv/www/vhosts/"
#simple-vhost.default-host = "www.example.org"
#simple-vhost.document-root = "/htdocs/"

##
## Format: .html
## -> ..../status-404.html for 'File not found'
#server.errorfile-prefix = "/usr/share/lighttpd/errors/status-"
#server.errorfile-prefix = "/srv/www/errors/status-"

## virtual directory listings
#dir-listing.activate = "enable"

## enable debugging
#debug.log-request-header = "enable"
#debug.log-response-header = "enable"
#debug.log-request-handling = "enable"
#debug.log-file-not-found = "enable"

### only root can use these options
#
# chroot() to directory (default: no chroot() )
#server.chroot = "/"

## change uid to (default: don't care)
server.username = "lighttpd"

## change uid to (default: don't care)
server.groupname = "lighttpd"

#### compress module
#compress.cache-dir = "/var/cache/lighttpd/compress/"
#compress.filetype = ("text/plain", "text/html")

#### proxy module
## read proxy.txt for more info
#proxy.server = ( ".php" =>
# ( "localhost" =>
# (
# "host" => "192.168.0.101",
# "port" => 80
# )
# )
# )

#### fastcgi module
## read fastcgi.txt for more info
## for PHP don't forget to set cgi.fix_pathinfo = 1 in the php.ini
fastcgi.server = ( ".php" => ((
"bin-path" => "/usr/bin/php",
"socket" => "/tmp/php.socket"
)))

#### CGI module
#cgi.assign = ( ".pl" => "/usr/bin/perl",
# ".cgi" => "/usr/bin/perl" )
#

#### SSL engine
#ssl.engine = "enable"
#ssl.pemfile = "/etc/ssl/private/lighttpd.pem"

#### status module
#status.status-url = "/server-status"
#status.config-url = "/server-config"

#### auth module
## read authentication.txt for more info
#auth.backend = "plain"
#auth.backend.plain.userfile = "lighttpd.user"
#auth.backend.plain.groupfile = "lighttpd.group"

#auth.backend.ldap.hostname = "localhost"
#auth.backend.ldap.base-dn = "dc=my-domain,dc=com"
#auth.backend.ldap.filter = "(uid=$)"

#auth.require = ( "/server-status" =>
# (
# "method" => "digest",
# "realm" => "download archiv",
# "require" => "user=jan"
# ),
# "/server-config" =>
# (
# "method" => "digest",
# "realm" => "download archiv",
# "require" => "valid-user"
# )
# )

#### url handling modules (rewrite, redirect, access)
#url.rewrite = ( "^/$" => "/server-status" )
#url.redirect = ( "^/wishlist/(.+)" => "http://www.123.org/$1" )
#### both rewrite/redirect support back reference to regex conditional using %n
#$HTTP["host"] =~ "^www\.(.*)" {
# url.redirect = ( "^/(.*)" => "http://%1/$1" )
#}

#
# define a pattern for the host url finding
# %% => % sign
# %0 => domain name + tld
# %1 => tld
# %2 => domain name without tld
# %3 => subdomain 1 name
# %4 => subdomain 2 name
#
#evhost.path-pattern = "/srv/www/vhosts/%3/htdocs/"

#### expire module
#expire.url = ( "/buggy/" => "access 2 hours", "/asdhas/" => "access plus 1 seconds 2 minutes")

#### ssi
#ssi.extension = ( ".shtml" )

#### rrdtool
#rrdtool.binary = "/usr/bin/rrdtool"
#rrdtool.db-name = "/var/lib/lighttpd/lighttpd.rrd"

#### setenv
#setenv.add-request-header = ( "TRAV_ENV" => "mysql://user@host/db" )
#setenv.add-response-header = ( "X-Secret-Message" => "42" )

## for mod_trigger_b4_dl
# trigger-before-download.gdbm-filename = "/var/lib/lighttpd/trigger.db"
# trigger-before-download.memcache-hosts = ( "127.0.0.1:11211" )
# trigger-before-download.trigger-url = "^/trigger/"
# trigger-before-download.download-url = "^/download/"
# trigger-before-download.deny-url = "http://127.0.0.1/index.html"
# trigger-before-download.trigger-timeout = 10

## for mod_cml
## don't forget to add index.cml to server.indexfiles
# cml.extension = ".cml"
# cml.memcache-hosts = ( "127.0.0.1:11211" )

#### variable usage:
## variable name without "." is auto prefixed by "var." and becomes "var.bar"
#bar = 1
#var.mystring = "foo"

## integer add
#bar += 1
## string concat, with integer cast as string, result: "www.foo1.com"
#server.name = "www." + mystring + var.bar + ".com"
## array merge
#index-file.names = (foo + ".php") + index-file.names
#index-file.names += (foo + ".php")

#### include
#include /etc/lighttpd/lighttpd-inc.conf
## same as above if you run: "lighttpd -f /etc/lighttpd/lighttpd.conf"
#include "lighttpd-inc.conf"

#### include_shell
#include_shell "echo var.a=1"
## the above is same as:
#var.a=1

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

More information about formatting options

Captcha
This question is for testing whether you are a human visitor and to prevent automated spam submissions.

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.