Lighttpd
Lighttpd is a fast, secure, and flexible open-source web server optimized for high-performance environments and low resource consumption.
Installation
Debian/Ubuntu
# Install lighttpd
sudo apt update
sudo apt install lighttpd
# Enable service to start on boot
sudo systemctl enable lighttpd
# Start lighttpd
sudo systemctl start lighttpd
# Verify installation
lighttpd -v
# Check status
sudo systemctl status lighttpd
CentOS/RHEL
# Install via EPEL repository
sudo yum install epel-release
sudo yum install lighttpd
# Enable and start
sudo systemctl enable lighttpd
sudo systemctl start lighttpd
macOS
# Install via Homebrew
brew install lighttpd
# Start service
brew services start lighttpd
# Manual start
lighttpd -f /usr/local/etc/lighttpd/lighttpd.conf
Compile from Source
# Download latest version
wget https://www.lighttpd.net/download/lighttpd-1.4.73.tar.gz
tar xzf lighttpd-1.4.73.tar.gz
cd lighttpd-1.4.73
# Configure and compile
./configure --prefix=/opt/lighttpd
make
sudo make install
# Create systemd service or init script
sudo cp ./doc/lighttpd.service /etc/systemd/system/
Basic Commands
# Check version
lighttpd -v
# Validate configuration
lighttpd -t -f /etc/lighttpd/lighttpd.conf
# Start server
sudo systemctl start lighttpd
sudo /etc/init.d/lighttpd start
# Stop server
sudo systemctl stop lighttpd
# Restart server
sudo systemctl restart lighttpd
# Reload configuration (graceful)
sudo systemctl reload lighttpd
sudo /etc/init.d/lighttpd reload
# Check if running
ps aux | grep lighttpd
sudo systemctl is-active lighttpd
Configuration File
Main Configuration Structure
# Location of lighttpd.conf
/etc/lighttpd/lighttpd.conf
Basic Configuration
# lighttpd.conf
# Server modules
server.modules = (
"mod_indexfile",
"mod_access",
"mod_alias",
"mod_accesslog",
"mod_compress",
"mod_dirlisting",
"mod_fastcgi",
"mod_rewrite"
)
# Server root (document root)
server.document-root = "/var/www/html"
# Listen on ports
server.port = 80
$SERVER["socket"] == ":443" {
ssl.engine = "enable"
ssl.pemfile = "/etc/ssl/private/server.pem"
}
# Process user/group
server.username = "www-data"
server.groupname = "www-data"
# Server PID file
server.pid-file = "/var/run/lighttpd.pid"
# Error and access logs
server.errorlog = "/var/log/lighttpd/error.log"
accesslog.filename = "/var/log/lighttpd/access.log"
# Default files to serve
index-file.names = (
"index.html",
"index.php",
"index.cgi"
)
# Gzip compression
compress.cache-dir = "/var/cache/lighttpd/compress"
compress.filetype = (
"text/plain",
"text/html",
"text/xml",
"text/css",
"text/javascript",
"application/json"
)
# Timeout settings
server.max-request-size = 2097152
server.max-connections = 1024
server.max-worker = 4
connection.idle-timeout = 300
Virtual Hosts
Single Virtual Host
# Basic virtual host configuration
$HTTP["host"] == "example.com" {
server.document-root = "/var/www/example.com"
server.errorlog = "/var/log/lighttpd/example.error.log"
accesslog.filename = "/var/log/lighttpd/example.access.log"
}
Multiple Virtual Hosts
# www.example.com
$HTTP["host"] == "www.example.com" {
server.document-root = "/var/www/example.com"
server.errorlog = "/var/log/lighttpd/example.error.log"
accesslog.filename = "/var/log/lighttpd/example.access.log"
}
# api.example.com
$HTTP["host"] == "api.example.com" {
server.document-root = "/var/www/api.example.com"
server.errorlog = "/var/log/lighttpd/api.error.log"
accesslog.filename = "/var/log/lighttpd/api.access.log"
}
# Catch-all redirect
$HTTP["host"] =~ ".*" {
url.redirect = (
"^/(.*)" => "https://www.example.com/$1"
)
}
Virtual Host with SSL
$SERVER["socket"] == ":443" {
ssl.engine = "enable"
ssl.pemfile = "/etc/ssl/private/server.pem"
$HTTP["host"] == "example.com" {
server.document-root = "/var/www/example.com"
}
}
# HTTP to HTTPS redirect
$HTTP["scheme"] == "http" {
$HTTP["host"] =~ "^(.*)$" {
url.redirect = ("^/(.*)" => "https://%1/$1")
}
}
FastCGI Setup
PHP Configuration
# Enable FastCGI module
server.modules += ("mod_fastcgi")
# FastCGI PHP setup
fastcgi.server = (
".php" => (
"localhost" => (
"socket" => "/run/php/php-fpm.sock",
"broken-scriptfilename" => "enable"
)
)
)
# Alternative TCP socket
fastcgi.server = (
".php" => (
"localhost" => (
"host" => "127.0.0.1",
"port" => 9000,
"broken-scriptfilename" => "enable"
)
)
)
Python FastCGI
fastcgi.server = (
".py" => (
"localhost" => (
"socket" => "/tmp/python-fcgi.sock",
"check-local" => "disable"
)
)
)
URL Rewriting and Redirects
Rewrite Rules
# Enable rewrite module
server.modules += ("mod_rewrite")
# Remove trailing slash
url.rewrite-once = (
"^(.+)/$" => "$1"
)
# Clean URLs (remove .php extension)
url.rewrite-once = (
"^/(.*)$" => "/index.php?q=$1"
)
# Pretty URLs for blog
url.rewrite-once = (
"^/([0-9]+)/([a-z0-9-]+)/?$" => "/post.php?id=$1&slug=$2"
)
# Force HTTPS
$HTTP["scheme"] == "http" {
url.redirect = (
"^/(.*)" => "https://%{HTTP_HOST}/$1"
)
}
Conditional Rewrites
# Rewrite if file doesn't exist
$HTTP["url"] !~ "\.(js|css|png|jpg|gif|ico)$" {
$HTTP["url"] !~ "^/admin/" {
url.rewrite-once = (
"^/(.*)$" => "/index.php?request=$1"
)
}
}
SSL/TLS Configuration
Basic HTTPS Setup
# Enable SSL
$SERVER["socket"] == ":443" {
ssl.engine = "enable"
ssl.pemfile = "/etc/ssl/private/server.pem"
ssl.ca-file = "/etc/ssl/certs/ca-bundle.crt"
}
# Redirect HTTP to HTTPS
$HTTP["scheme"] == "http" {
$HTTP["host"] =~ "(.*)" {
url.redirect = ("^/(.*)" => "https://%1/$1")
}
}
Modern TLS Configuration
$SERVER["socket"] == ":443" {
ssl.engine = "enable"
ssl.pemfile = "/etc/ssl/private/server.pem"
ssl.ca-file = "/etc/ssl/certs/ca.pem"
# TLS versions (disable old versions)
ssl.openssl.ssl-conf-cmd = (
"MinProtocol" => "TLSv1.2",
"Options" => "-ServerPreference"
)
# Ciphers
ssl.cipher-list = "HIGH:!aNULL:!MD5"
# HSTS header
setenv.add-response-header = (
"Strict-Transport-Security" => "max-age=31536000; includeSubDomains"
)
}
Security Configuration
Access Control
# Enable access module
server.modules += ("mod_access")
# Block directory listing
$HTTP["url"] =~ "^/private/" {
url.access-deny = ("~")
}
# Disable access to certain files
url.access-deny = (
".htaccess",
".htpasswd",
"*.conf",
"*.log"
)
# IP-based access control
$HTTP["remoteip"] == "192.168.1.100" {
url.access-deny = ("/admin/")
}
# Allow only specific IPs to /admin
$HTTP["url"] =~ "^/admin/" {
$HTTP["remoteip"] !~ "^(192\.168\.1\.|10\.0\.0\.)" {
url.access-deny = ("~")
}
}
Basic Authentication
# Enable auth module
server.modules += ("mod_auth")
# Create password file
# htpasswd -c /etc/lighttpd/.htpasswd username
auth.backend = "plain"
auth.backend.plain.userfile = "/etc/lighttpd/.htpasswd"
# Protect directory
$HTTP["url"] =~ "^/admin/" {
auth.require = (
"" => (
"method" => "basic",
"realm" => "Admin Area",
"require" => "user=admin"
)
)
}
Performance Tuning
Connection Settings
# Maximum connections
server.max-connections = 2048
# Worker threads
server.max-worker = 4
# Request body size limit
server.max-request-size = 2097152 # 2MB
# Connection timeout
connection.idle-timeout = 300
# Keep-alive timeout
connection.request-timeout = 20
Caching and Compression
# Enable compression
server.modules += ("mod_compress")
compress.cache-dir = "/var/cache/lighttpd/compress"
compress.filetype = (
"text/plain",
"text/html",
"text/xml",
"text/css",
"application/javascript",
"application/json",
"image/svg+xml"
)
# Set cache headers
setenv.add-response-header = (
"Cache-Control" => "public, max-age=3600"
)
# Etag configuration
etag.use-inode = "enable"
etag.use-mtime = "enable"
etag.use-size = "enable"
Monitoring and Logging
Log Configuration
# Access log format
accesslog.filename = "/var/log/lighttpd/access.log"
accesslog.format = "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\""
# Conditional logging
$HTTP["url"] =~ "\.(css|js|jpg|png|gif)$" {
accesslog.filename = "/dev/null"
}
# Error log
server.errorlog = "/var/log/lighttpd/error.log"
Log Rotation
# Setup logrotate for lighttpd
sudo cat > /etc/logrotate.d/lighttpd << 'EOF'
/var/log/lighttpd/*.log {
daily
missingok
rotate 7
compress
delaycompress
notifempty
create 0640 www-data www-data
sharedscripts
postrotate
/bin/kill -SIGUSR1 `cat /var/run/lighttpd.pid 2>/dev/null` 2>/dev/null || true
endscript
}
EOF
Troubleshooting
Check Configuration
# Validate syntax
lighttpd -t -f /etc/lighttpd/lighttpd.conf
# Test start with debug output
sudo lighttpd -D -f /etc/lighttpd/lighttpd.conf
# Verbose output
sudo lighttpd -D -f /etc/lighttpd/lighttpd.conf 2>&1 | head -50
Common Issues
# Port already in use
sudo lsof -i :80
sudo netstat -tulpn | grep :80
# Check permissions
ls -la /var/www/html/
ls -la /var/log/lighttpd/
sudo chown -R www-data:www-data /var/www/
# Check PHP-FPM connection
sudo systemctl status php-fpm
netstat -an | grep 9000
# View recent errors
tail -f /var/log/lighttpd/error.log
# Check resource usage
ps aux | grep lighttpd
Example Configurations
Static Website
server.modules = (
"mod_indexfile",
"mod_access",
"mod_alias",
"mod_accesslog",
"mod_compress",
"mod_dirlisting"
)
server.document-root = "/var/www/html"
server.port = 80
index-file.names = ("index.html")
compress.filetype = (
"text/plain",
"text/html",
"text/css",
"application/javascript"
)
accesslog.filename = "/var/log/lighttpd/access.log"
server.errorlog = "/var/log/lighttpd/error.log"
PHP Application
server.modules = (
"mod_indexfile",
"mod_access",
"mod_alias",
"mod_accesslog",
"mod_fastcgi",
"mod_rewrite",
"mod_compress"
)
server.document-root = "/var/www/app"
index-file.names = ("index.php", "index.html")
fastcgi.server = (
".php" => (
"localhost" => (
"socket" => "/run/php/php-fpm.sock",
"broken-scriptfilename" => "enable"
)
)
)
url.rewrite-once = (
"^/(.*)$" => "/index.php?request=$1"
)
Reverse Proxy
server.modules += ("mod_proxy")
$HTTP["url"] =~ "^/api" {
proxy.server = (
"" => (
"host" => "127.0.0.1",
"port" => 3000
)
)
}
$HTTP["url"] =~ "^/admin" {
proxy.server = (
"" => (
"host" => "admin-server.internal",
"port" => 8080
)
)
}
Best Practices
- Always validate configuration before restarting:
lighttpd -t -f /etc/lighttpd/lighttpd.conf - Use separate log files for different virtual hosts
- Enable gzip compression for text content to reduce bandwidth
- Set appropriate timeout values based on application needs
- Implement HTTP to HTTPS redirect for security
- Use strong SSL/TLS ciphers and protocols
- Monitor access and error logs regularly
- Keep system and lighttpd updated with security patches
- Test configuration changes in staging before production
- Use conditional logging to reduce log file size
Resources
- Lighttpd Official Documentation
- Configuration Reference
- Module Documentation
- GitHub Repository
- Performance Guide
Last updated: 2025-03-30