Set up Lighttpd web server with Redis caching to dramatically improve website performance through intelligent content caching, reducing server load and response times for high-traffic applications.
Prerequisites
- Root or sudo access
- Basic Linux command line knowledge
- Understanding of web server concepts
What this solves
Lighttpd with Redis caching creates a high-performance web serving stack that dramatically reduces response times and server load. This combination is ideal for content-heavy websites, API endpoints, and applications that serve the same content to multiple users frequently.
Step-by-step installation
Update system packages
Start by updating your package manager to ensure you get the latest versions of all components.
sudo apt update && sudo apt upgrade -y
Install Lighttpd web server
Install Lighttpd along with essential modules for caching and FastCGI support.
sudo apt install -y lighttpd lighttpd-mod-webdav
Install Redis caching server
Install Redis server which will serve as the caching backend for Lighttpd.
sudo apt install -y redis-server redis-tools
Install Redis module for Lighttpd
Install the Redis module that allows Lighttpd to communicate with Redis for caching operations.
sudo apt install -y lighttpd-mod-trigger-b4-dl
Configure Redis for optimal caching
Configure Redis with settings optimized for web caching, including memory limits and eviction policies.
# Set maximum memory for cache (adjust based on your system)
maxmemory 256mb
maxmemory-policy allkeys-lru
Enable persistence for cache recovery
save 900 1
save 300 10
save 60 10000
Optimize for web caching
tcp-keepalive 300
timeout 0
Security settings
bind 127.0.0.1
protected-mode yes
requirepass your_redis_password_here
Logging
loglevel notice
logfile /var/log/redis/redis-server.log
Start and enable Redis service
Enable Redis to start automatically on boot and start the service immediately.
sudo systemctl enable redis-server
sudo systemctl start redis-server
sudo systemctl status redis-server
Create Lighttpd main configuration
Configure Lighttpd with performance optimizations and Redis caching integration.
server.modules = (
"mod_indexfile",
"mod_access",
"mod_alias",
"mod_redirect",
"mod_rewrite",
"mod_compress",
"mod_expire",
"mod_setenv",
"mod_fastcgi",
"mod_trigger_b4_dl"
)
Basic server settings
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.max-worker = 4
server.max-request-size = 2048
Index files
index-file.names = ("index.php", "index.html", "index.htm", "default.htm")
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"
)
Compression for better performance
compress.cache-dir = "/var/cache/lighttpd/compress/"
compress.filetype = ("application/javascript", "text/css", "text/html", "text/plain")
Expire headers for static content
expire.url = (
"/images/" => "access plus 1 months",
"/css/" => "access plus 1 weeks",
"/js/" => "access plus 1 weeks"
)
Configure Redis caching module
Create a separate configuration file for Redis caching integration with Lighttpd.
# Redis caching configuration
Note: This requires custom implementation as Lighttpd doesn't have native Redis support
We'll use trigger_b4_dl for basic caching functionality
Enable trigger before download for cache logic
trigger-before-download.gdbm-filename = "/var/cache/lighttpd/trigger.db"
trigger-before-download.memcache-hosts = ( "127.0.0.1:11211" )
Static file caching with etags
static-file.etags = "enable"
Advanced expire rules for different content types
expire.url = (
"/static/" => "access plus 1 months",
"/media/" => "access plus 1 months",
"/css/" => "access plus 1 weeks",
"/js/" => "access plus 1 weeks",
"/images/" => "access plus 1 months",
"/fonts/" => "access plus 1 months"
)
Cache headers for API responses
setenv.add-response-header = (
"Cache-Control" => "public, max-age=3600",
"Vary" => "Accept-Encoding"
)
Create cache directories with proper permissions
Create necessary cache directories and set appropriate ownership for the web server user.
sudo mkdir -p /var/cache/lighttpd/{compress,uploads}
sudo chown -R www-data:www-data /var/cache/lighttpd
sudo chmod -R 755 /var/cache/lighttpd
Create log directory
sudo mkdir -p /var/log/lighttpd
sudo chown www-data:www-data /var/log/lighttpd
sudo chmod 755 /var/log/lighttpd
Enable Redis cache configuration
Enable the Redis cache configuration module in Lighttpd.
sudo lighttpd-enable-mod redis-cache
sudo systemctl reload lighttpd
Create a test website
Create a sample website to test caching functionality with dynamic and static content.
Lighttpd + Redis Cache Test
Lighttpd with Redis Caching
Current time:
This page tests caching functionality.
sudo mkdir -p /var/www/html/{css,js,images}
sudo chown -R www-data:www-data /var/www/html
sudo chmod -R 644 /var/www/html/*
sudo find /var/www/html -type d -exec chmod 755 {} \;
Create sample CSS and JavaScript files
Add static assets to test compression and caching of different content types.
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 20px;
background-color: #f4f4f4;
}
h1 {
color: #333;
text-align: center;
}
p {
line-height: 1.6;
color: #666;
}
img {
display: block;
margin: 20px auto;
border-radius: 8px;
}
document.addEventListener('DOMContentLoaded', function() {
const timeElement = document.getElementById('time');
const now = new Date();
timeElement.textContent = now.toLocaleString();
// Test AJAX request for cache testing
console.log('Page loaded at: ' + now.toLocaleString());
});
Configure Redis connection script
Create a PHP script to demonstrate Redis integration for dynamic caching.
sudo apt install -y php-fpm php-redis
connect('127.0.0.1', 6379);
$redis->auth('your_redis_password_here');
$cache_key = 'page_views';
$views = $redis->get($cache_key);
if ($views === false) {
$views = 1;
} else {
$views++;
}
$redis->set($cache_key, $views, 3600); // Cache for 1 hour
header('Content-Type: application/json');
header('Cache-Control: public, max-age=300'); // Cache for 5 minutes
echo json_encode([
'page_views' => $views,
'timestamp' => date('Y-m-d H:i:s'),
'cached_until' => date('Y-m-d H:i:s', time() + 300)
]);
} catch (Exception $e) {
http_response_code(500);
echo json_encode(['error' => 'Cache connection failed']);
}
?>
Configure PHP-FPM for Lighttpd
Configure FastCGI to handle PHP requests through Lighttpd.
## FastCGI programs have the same functionality as CGI programs,
but are considerably faster through lower interpreter startup
time and socketed communication
fastcgi.server += ( ".php" =>
((
"bin-path" => "/usr/bin/php-cgi",
"socket" => "/var/run/lighttpd/php.socket",
"max-procs" => 2,
"idle-timeout" => 20,
"bin-environment" => (
"PHP_FCGI_CHILDREN" => "4",
"PHP_FCGI_MAX_REQUESTS" => "10000"
),
"bin-copy-environment" => (
"PATH", "SHELL", "USER"
),
"broken-scriptfilename" => "enable"
))
)
sudo lighttpd-enable-mod fastcgi-php
Start and enable services
Enable and start both Lighttpd and ensure Redis is running properly.
sudo systemctl enable lighttpd
sudo systemctl start lighttpd
sudo systemctl status lighttpd
sudo systemctl status redis-server
Configure caching performance optimization
Optimize Redis memory settings
Configure Redis for optimal memory usage and cache eviction policies specific to web caching.
redis-cli -a your_redis_password_here CONFIG SET maxmemory-policy allkeys-lru
redis-cli -a your_redis_password_here CONFIG SET maxmemory 512mb
redis-cli -a your_redis_password_here CONFIG REWRITE
Monitor cache performance
Create monitoring scripts to track cache hit rates and performance metrics.
#!/bin/bash
Redis cache statistics
echo "=== Redis Cache Statistics ==="
redis-cli -a your_redis_password_here INFO stats | grep -E "keyspace_hits|keyspace_misses|used_memory_human|connected_clients"
Lighttpd status
echo -e "\n=== Lighttpd Status ==="
sudo systemctl is-active lighttpd
sudo netstat -tlnp | grep :80
Cache directory sizes
echo -e "\n=== Cache Directory Usage ==="
du -sh /var/cache/lighttpd/*
Recent access logs
echo -e "\n=== Recent Access Patterns ==="
sudo tail -n 10 /var/log/lighttpd/access.log 2>/dev/null || echo "No access log found"
sudo chmod +x /usr/local/bin/cache-stats.sh
Verify your setup
Test the caching functionality and verify both services are working correctly.
# Check service status
sudo systemctl status lighttpd
sudo systemctl status redis-server
Test Redis connection
redis-cli -a your_redis_password_here ping
Test web server response
curl -I http://localhost/
curl -I http://localhost/cache-test.php
Check cache hit statistics
redis-cli -a your_redis_password_here INFO stats | grep keyspace
Monitor cache performance
/usr/local/bin/cache-stats.sh
Test compression
curl -H "Accept-Encoding: gzip" -v http://localhost/ | head
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| Lighttpd won't start | Configuration syntax error | sudo lighttpd -t -f /etc/lighttpd/lighttpd.conf |
| Redis connection refused | Redis not running or wrong password | sudo systemctl start redis-server and check password |
| Permission denied errors | Incorrect file ownership | sudo chown -R www-data:www-data /var/www/html |
| PHP files not executing | FastCGI module not enabled | sudo lighttpd-enable-mod fastcgi-php |
| Cache not working | Cache headers not set | Check expire configuration and cache headers |
| High memory usage | Redis maxmemory not set | Set appropriate maxmemory in Redis config |
Next steps
Automated install script
Run this to automate the entire setup
#!/usr/bin/env bash
set -euo pipefail
# Production Lighttpd + Redis Install Script
# Configures high-performance web serving with caching
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
# Configuration
REDIS_PASSWORD="${REDIS_PASSWORD:-$(openssl rand -base64 32)}"
REDIS_MEMORY="${REDIS_MEMORY:-256mb}"
DOMAIN="${1:-example.com}"
# Usage message
if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
echo "Usage: $0 [domain] [redis_memory]"
echo "Example: $0 mysite.com 512mb"
exit 0
fi
# Check prerequisites
if [[ $EUID -ne 0 ]]; then
echo -e "${RED}Error: This script must be run as root${NC}"
exit 1
fi
# Detect distribution
if [[ ! -f /etc/os-release ]]; then
echo -e "${RED}Error: Cannot detect OS distribution${NC}"
exit 1
fi
. /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_UPDATE="apt update && apt upgrade -y"
PKG_INSTALL="apt install -y"
REDIS_SERVICE="redis-server"
REDIS_CONFIG="/etc/redis/redis.conf"
LIGHTTPD_CONFIG="/etc/lighttpd/lighttpd.conf"
WEB_USER="www-data"
FIREWALL_CMD="ufw allow 80"
;;
almalinux|rocky|centos|rhel|ol)
PKG_MGR="dnf"
PKG_UPDATE="dnf update -y"
PKG_INSTALL="dnf install -y"
REDIS_SERVICE="redis"
REDIS_CONFIG="/etc/redis/redis.conf"
LIGHTTPD_CONFIG="/etc/lighttpd/lighttpd.conf"
WEB_USER="lighttpd"
FIREWALL_CMD="firewall-cmd --permanent --add-service=http && firewall-cmd --reload"
;;
fedora)
PKG_MGR="dnf"
PKG_UPDATE="dnf update -y"
PKG_INSTALL="dnf install -y"
REDIS_SERVICE="redis"
REDIS_CONFIG="/etc/redis/redis.conf"
LIGHTTPD_CONFIG="/etc/lighttpd/lighttpd.conf"
WEB_USER="lighttpd"
FIREWALL_CMD="firewall-cmd --permanent --add-service=http && firewall-cmd --reload"
;;
amzn)
PKG_MGR="yum"
PKG_UPDATE="yum update -y"
PKG_INSTALL="yum install -y"
REDIS_SERVICE="redis"
REDIS_CONFIG="/etc/redis.conf"
LIGHTTPD_CONFIG="/etc/lighttpd/lighttpd.conf"
WEB_USER="lighttpd"
FIREWALL_CMD="iptables -I INPUT -p tcp --dport 80 -j ACCEPT"
;;
*)
echo -e "${RED}Error: Unsupported distribution: $ID${NC}"
exit 1
;;
esac
# Cleanup function
cleanup() {
echo -e "${YELLOW}Cleaning up on error...${NC}"
systemctl stop lighttpd 2>/dev/null || true
systemctl stop $REDIS_SERVICE 2>/dev/null || true
}
trap cleanup ERR
echo -e "${GREEN}[1/8] Updating system packages...${NC}"
$PKG_UPDATE
echo -e "${GREEN}[2/8] Installing Lighttpd web server...${NC}"
if [[ "$ID" =~ ^(ubuntu|debian)$ ]]; then
$PKG_INSTALL lighttpd lighttpd-mod-webdav
else
$PKG_INSTALL lighttpd lighttpd-fastcgi
fi
echo -e "${GREEN}[3/8] Installing Redis server...${NC}"
$PKG_INSTALL redis redis-tools openssl
echo -e "${GREEN}[4/8] Configuring Redis for web caching...${NC}"
# Backup original config
cp $REDIS_CONFIG ${REDIS_CONFIG}.backup
cat > $REDIS_CONFIG << EOF
# Redis configuration for web caching
bind 127.0.0.1
port 6379
protected-mode yes
requirepass $REDIS_PASSWORD
# Memory settings
maxmemory $REDIS_MEMORY
maxmemory-policy allkeys-lru
# Persistence
save 900 1
save 300 10
save 60 10000
# Performance
tcp-keepalive 300
timeout 0
# Logging
loglevel notice
logfile /var/log/redis/redis-server.log
# Security
supervised systemd
daemonize no
EOF
echo -e "${GREEN}[5/8] Starting Redis service...${NC}"
systemctl enable $REDIS_SERVICE
systemctl start $REDIS_SERVICE
echo -e "${GREEN}[6/8] Configuring Lighttpd...${NC}"
# Backup original config
cp $LIGHTTPD_CONFIG ${LIGHTTPD_CONFIG}.backup
cat > $LIGHTTPD_CONFIG << EOF
server.modules = (
"mod_indexfile",
"mod_access",
"mod_alias",
"mod_redirect",
"mod_rewrite",
"mod_compress",
"mod_expire",
"mod_setenv"
)
# Basic server settings
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 = "$WEB_USER"
server.groupname = "$WEB_USER"
server.port = 80
# Performance tuning
server.max-connections = 1024
server.max-fds = 2048
server.max-worker = 4
server.max-request-size = 2048
# Index files
index-file.names = ("index.php", "index.html", "index.htm")
# MIME types
mimetype.assign = (
".pdf" => "application/pdf",
".sig" => "application/pgp-signature",
".class" => "application/octet-stream",
".ps" => "application/postscript",
".gz" => "application/x-gzip",
".tar" => "application/x-tar",
".zip" => "application/zip",
".mp3" => "audio/mpeg",
".ogg" => "application/ogg",
".wav" => "audio/x-wav",
".gif" => "image/gif",
".jpg" => "image/jpeg",
".jpeg" => "image/jpeg",
".png" => "image/png",
".css" => "text/css",
".html" => "text/html",
".htm" => "text/html",
".js" => "text/javascript",
".txt" => "text/plain",
".dtd" => "text/xml",
".xml" => "text/xml",
"" => "application/octet-stream"
)
# Compression
compress.cache-dir = "/var/cache/lighttpd/compress/"
compress.filetype = ("application/javascript", "text/css", "text/html", "text/plain")
# Expire headers for static content
expire.url = (
"/css/" => "access plus 1 months",
"/js/" => "access plus 1 months",
"/images/" => "access plus 1 months"
)
EOF
echo -e "${GREEN}[7/8] Setting up directories and permissions...${NC}"
mkdir -p /var/www/html
mkdir -p /var/cache/lighttpd/{uploads,compress}
mkdir -p /var/log/redis
chown -R $WEB_USER:$WEB_USER /var/www/html
chown -R $WEB_USER:$WEB_USER /var/cache/lighttpd
chmod 755 /var/www/html
chmod 755 /var/cache/lighttpd/{uploads,compress}
# Create test page
cat > /var/www/html/index.html << EOF
<!DOCTYPE html>
<html>
<head>
<title>Lighttpd + Redis Server</title>
<style>
body { font-family: Arial, sans-serif; margin: 40px; }
.success { color: green; }
.info { background: #f0f0f0; padding: 20px; border-radius: 5px; }
</style>
</head>
<body>
<h1 class="success">Lighttpd + Redis Successfully Installed!</h1>
<div class="info">
<h3>Server Information:</h3>
<ul>
<li>Domain: $DOMAIN</li>
<li>Redis Memory: $REDIS_MEMORY</li>
<li>Web Server: Lighttpd 1.4</li>
<li>Cache: Redis</li>
</ul>
</div>
</body>
</html>
EOF
chown $WEB_USER:$WEB_USER /var/www/html/index.html
echo -e "${GREEN}[8/8] Starting services and configuring firewall...${NC}"
systemctl enable lighttpd
systemctl start lighttpd
# Configure firewall
if command -v ufw >/dev/null 2>&1 && [[ "$ID" =~ ^(ubuntu|debian)$ ]]; then
ufw allow 80/tcp >/dev/null 2>&1 || true
elif command -v firewall-cmd >/dev/null 2>&1; then
firewall-cmd --permanent --add-service=http >/dev/null 2>&1 || true
firewall-cmd --reload >/dev/null 2>&1 || true
fi
echo -e "${GREEN}Installation completed successfully!${NC}"
echo ""
echo -e "${YELLOW}Configuration Details:${NC}"
echo "Redis Password: $REDIS_PASSWORD"
echo "Redis Memory Limit: $REDIS_MEMORY"
echo "Web Root: /var/www/html"
echo "Lighttpd Config: $LIGHTTPD_CONFIG"
echo "Redis Config: $REDIS_CONFIG"
echo ""
echo -e "${GREEN}Service Status:${NC}"
systemctl --no-pager status lighttpd --lines=0
systemctl --no-pager status $REDIS_SERVICE --lines=0
echo ""
echo -e "${GREEN}Test your installation at: http://$(hostname -I | awk '{print $1}')${NC}"
Review the script before running. Execute with: bash install.sh