Install and configure Lighttpd web server with SSL and FastCGI for lightweight hosting

Intermediate 25 min Apr 03, 2026 41 views
Ubuntu 24.04 Ubuntu 22.04 Debian 12 AlmaLinux 9 Rocky Linux 9 Fedora 41

Set up Lighttpd web server with SSL certificates from Let's Encrypt and FastCGI support for PHP applications. Configure virtual hosts, optimize performance, and implement security hardening for production hosting.

Prerequisites

  • Root or sudo access
  • Domain name pointing to your server
  • Basic command line knowledge

What this solves

Lighttpd is a lightweight, high-performance web server that uses minimal system resources while delivering fast response times. This tutorial shows you how to install and configure Lighttpd with SSL certificates, FastCGI support for PHP applications, and production-ready security settings for hosting websites efficiently.

Step-by-step installation

Update system packages

Start by updating your package manager to ensure you get the latest versions of all packages.

sudo apt update && sudo apt upgrade -y
sudo dnf update -y

Install Lighttpd and dependencies

Install Lighttpd web server along with PHP-FPM for FastCGI support and Certbot for SSL certificates.

sudo apt install -y lighttpd php-fpm php-cli php-mysql php-gd php-curl certbot
sudo dnf install -y lighttpd php-fpm php-cli php-mysqlnd php-gd php-curl certbot

Configure firewall rules

Open HTTP and HTTPS ports in the firewall to allow web traffic to reach your server.

sudo ufw allow 'WWW Full'
sudo ufw enable
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload

Configure main Lighttpd settings

Edit the main configuration file to enable modules and set basic server parameters.

server.modules = (
	"mod_access",
	"mod_alias",
	"mod_compress",
	"mod_redirect",
	"mod_rewrite",
	"mod_setenv",
	"mod_fastcgi",
	"mod_accesslog"
)

server.document-root        = "/var/www/html"
server.upload-dirs          = ( "/var/cache/lighttpd/uploads" )
server.errorlog             = "/var/log/lighttpd/error.log"
server.pid-file             = "/var/run/lighttpd.pid"
server.username             = "www-data"
server.groupname            = "www-data"
server.port                 = 80

Performance tuning

server.max-connections = 1024 server.max-fds = 2048 server.stat-cache-engine = "simple" server.max-worker = 4

Security headers

setenv.add-response-header = ( "X-Frame-Options" => "DENY", "X-Content-Type-Options" => "nosniff", "X-XSS-Protection" => "1; mode=block", "Referrer-Policy" => "strict-origin-when-cross-origin" )

MIME types

mimetype.assign = ( ".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", "" => "application/octet-stream" )

Configure PHP FastCGI

Set up FastCGI to handle PHP requests efficiently through PHP-FPM.

fastcgi.server += ( ".php" =>
	((
		"socket" => "/var/run/php/php-fpm.sock",
		"broken-scriptfilename" => "enable"
	))
)

Enable FastCGI configuration

Enable the FastCGI PHP configuration module.

sudo lighttpd-enable-mod fastcgi-php

Configure virtual host

Create a virtual host configuration for your domain. Replace example.com with your actual domain name.

$HTTP["host"] == "example.com" {
	server.document-root = "/var/www/example.com/public"
	accesslog.filename = "/var/log/lighttpd/example.com-access.log"
	
	# PHP FastCGI for this virtual host
	fastcgi.server = ( ".php" =>
		((
			"socket" => "/var/run/php/php-fpm.sock",
			"broken-scriptfilename" => "enable"
		))
	)
	
	# Security settings
	$HTTP["url"] =~ "^/(\.|_)" {
		url.access-deny = ("")
	}
	
	# Cache static files
	$HTTP["url"] =~ "\.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2)$" {
		expire.url = ( "" => "access plus 1 months" )
	}
}

Create document root and test page

Create the directory structure for your website and a test PHP file.

sudo mkdir -p /var/www/example.com/public
sudo chown -R www-data:www-data /var/www/example.com
sudo chmod -R 755 /var/www/example.com

Enable virtual host configuration

Enable the virtual host configuration and restart Lighttpd to apply changes.

sudo ln -s /etc/lighttpd/conf-available/90-example.conf /etc/lighttpd/conf-enabled/
sudo systemctl restart lighttpd
sudo systemctl enable lighttpd

Obtain SSL certificate with Let's Encrypt

Use Certbot to obtain a free SSL certificate for your domain. Replace example.com with your actual domain.

sudo certbot certonly --webroot -w /var/www/example.com/public -d example.com -d www.example.com

Configure SSL in Lighttpd

Enable SSL module and configure HTTPS with the Let's Encrypt certificate.

sudo lighttpd-enable-mod ssl
$HTTP["scheme"] == "http" {
	$HTTP["host"] =~ ".*" {
		url.redirect = (".*" => "https://%0$0")
	}
}

$SERVER["socket"] == ":443" {
	ssl.engine = "enable"
	ssl.pemfile = "/etc/ssl/private/lighttpd-combined.pem"
	ssl.ca-file = "/etc/ssl/certs/ca-certificates.crt"
	
	# Modern SSL configuration
	ssl.cipher-list = "ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384"
	ssl.honor-cipher-order = "enable"
	ssl.disable-client-renegotiation = "enable"
}

Create combined SSL certificate file

Lighttpd requires the private key and certificate in a single file.

sudo cat /etc/letsencrypt/live/example.com/privkey.pem /etc/letsencrypt/live/example.com/cert.pem > /etc/ssl/private/lighttpd-combined.pem
sudo chmod 600 /etc/ssl/private/lighttpd-combined.pem
sudo chown root:root /etc/ssl/private/lighttpd-combined.pem

Configure automatic certificate renewal

Create a renewal hook to recreate the combined certificate file when Let's Encrypt renews certificates.

#!/bin/bash
cat /etc/letsencrypt/live/example.com/privkey.pem /etc/letsencrypt/live/example.com/cert.pem > /etc/ssl/private/lighttpd-combined.pem
chmod 600 /etc/ssl/private/lighttpd-combined.pem
systemctl reload lighttpd
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/lighttpd-reload.sh

Configure compression and caching

Enable gzip compression and browser caching to improve performance.

compress.cache-dir = "/var/cache/lighttpd/compress/"
compress.filetype = (
	"application/javascript",
	"application/x-javascript",
	"application/json",
	"application/xml",
	"text/css",
	"text/html",
	"text/javascript",
	"text/plain",
	"text/xml"
)
compress.max-filesize = 2048
sudo mkdir -p /var/cache/lighttpd/compress
sudo chown www-data:www-data /var/cache/lighttpd/compress
sudo lighttpd-enable-mod compress

Restart Lighttpd with SSL enabled

Restart the web server to apply all SSL and performance configurations.

sudo systemctl restart lighttpd
sudo systemctl status lighttpd

Configure log rotation

Set up log rotation to prevent log files from consuming excessive disk space, similar to monitoring setups covered in our disk usage monitoring tutorial.

/var/log/lighttpd/*.log {
	daily
	missingok
	rotate 52
	compress
	notifempty
	sharedscripts
	postrotate
		if [ -f /var/run/lighttpd.pid ]; then
			/bin/kill -USR1 cat /var/run/lighttpd.pid
		fi
	endscript
}

Performance tuning

Optimize system limits

Increase system limits for better performance under load, building on concepts from system performance optimization.

www-data soft nofile 65536
www-data hard nofile 65536

Configure PHP-FPM optimization

Optimize PHP-FPM settings for better performance with Lighttpd.

[www]
user = www-data
group = www-data
listen = /var/run/php/php-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500

php_admin_value[memory_limit] = 256M
php_admin_value[max_execution_time] = 30
php_admin_value[upload_max_filesize] = 10M
php_admin_value[post_max_size] = 10M

Restart services

Restart both PHP-FPM and Lighttpd to apply performance optimizations.

sudo systemctl restart php8.3-fpm
sudo systemctl restart lighttpd
sudo systemctl restart php-fpm
sudo systemctl restart lighttpd

Verify your setup

Test your Lighttpd installation and configuration with these verification commands.

sudo systemctl status lighttpd
sudo systemctl status php-fpm
sudo lighttpd -t -f /etc/lighttpd/lighttpd.conf
curl -I https://example.com
ssl-cert-check -c /etc/ssl/private/lighttpd-combined.pem
Note: Replace example.com with your actual domain name when testing. The PHP info page should display correctly over HTTPS.

Security hardening

Hide server information

Configure Lighttpd to hide version information and server details from HTTP headers.

server.tag = ""
server.server-root = "/var/www"

Deny access to sensitive files

$HTTP["url"] =~ "/(\.|~)" { url.access-deny = ("") }

Deny access to backup files

$HTTP["url"] =~ "\.(bak|config|dist|fla|inc|ini|log|psd|sh|sql|swp)$" { url.access-deny = ("") }

Rate limiting

connection.kbytes-per-second = 0 server.kbytes-per-second = 0
sudo ln -s /etc/lighttpd/conf-available/10-security.conf /etc/lighttpd/conf-enabled/

Configure fail2ban protection

Set up fail2ban to protect against brute force attacks on your web server.

sudo apt install -y fail2ban
sudo dnf install -y fail2ban
[lighttpd-auth]
enabled = true
port = http,https
filter = lighttpd-auth
logpath = /var/log/lighttpd/error.log
maxretry = 3
bantime = 3600
sudo systemctl enable --now fail2ban
Never use chmod 777. It gives every user on the system full access to your files. Instead, fix ownership with chown and use minimal permissions like 755 for directories and 644 for files.

Common issues

SymptomCauseFix
403 Forbidden errorIncorrect file permissionssudo chown -R www-data:www-data /var/www && sudo chmod -R 755 /var/www
PHP files download instead of executingFastCGI not configured properlyCheck FastCGI configuration and restart sudo systemctl restart php-fpm lighttpd
SSL certificate errorsCombined certificate file missing or incorrectRecreate combined certificate: sudo cat /etc/letsencrypt/live/example.com/privkey.pem /etc/letsencrypt/live/example.com/cert.pem > /etc/ssl/private/lighttpd-combined.pem
Server won't startConfiguration syntax errorTest configuration: sudo lighttpd -t -f /etc/lighttpd/lighttpd.conf
High memory usageToo many PHP-FPM processesAdjust pm.max_children in PHP-FPM pool configuration

Next steps

Automated install script

Run this to automate the entire setup

#lighttpd #web-server #ssl-certificates #fastcgi #php #performance

Need help?

Don't want to manage this yourself?

We handle infrastructure for businesses that depend on uptime. From initial setup to ongoing operations.

Talk to an engineer