Lighttpd [Link] uses fewer resources than Apache2 or Nginx, making it ideal for handling a lot of traffic with less memory and CPU.
It’s a great choice for low-powered devices like the Raspberry Pi Zero. While other web servers can work too, Lighttpd will likely perform better on such limited hardware.
INSTALLING WEB SERVER PLUS PHP
sudo apt update && sudo apt upgrade -y sudo apt install lighttpd -y
sudo apt install php7.4 php7.4-fpm php7.4-mysql php7.4-cli php7.4-curl php7.4-xml curl -y
sudo nano /etc/php/7.4/fpm/pool.d/www.conf
;listen = /run/php/php7.4-fpm.sock listen = 127.0.0.1:9000
#"bin-path" => "/usr/bin/php-cgi",
#"socket" => "/var/run/lighttpd/php.socket",
"host" => "127.0.0.1",
"port" => "9000",
sudo lighty-enable-mod fastcgi sudo lighty-enable-mod fastcgi-php sudo systemctl restart lighttpd php7.4-fpm
rm /var/www/html/index.lighttpd.html echo '<?php echo "HTTP_HOST: " . $_SERVER["HTTP_HOST"] . " SERVER_NAME: " . $_SERVER["SERVER_NAME"] ?>' | sudo tee /var/www/html/index.php sudo chown -R www-data: /var/www/html/ sudo chmod -R 755 /var/www/html/
At this point, any HTTP request to this server will be served with the same page. Consider using Virtual Hosts to server multiple sites based on its Host header.
SETTING A VIRTUAL HOST
sudo nano /etc/lighttpd/lighttpd.conf
... include_shell "/usr/share/lighttpd/create-mime.conf.pl" include_shell "cat /etc/lighttpd/vhosts.d/*.conf" include "/etc/lighttpd/conf-enabled/*.conf" ...
sudo mkdir -p /etc/lighttpd/vhosts.d/ sudo nano /etc/lighttpd/vhosts.d/localhost.conf
$HTTP["host"] =~ "(^|.)localhost$" {
server.document-root = "/var/www/html/localhost"
}
sudo mkdir -p /var/www/html/localhost echo 'VHOST: localhost' | sudo tee /var/www/html/localhost/index.html
sudo lighttpd -t -f /etc/lighttpd/lighttpd.conf && sudo systemctl restart lighttpd.service
curl http://127.0.0.1 curl http://localhost
While the first request is served with the default site, the second request will be served with a different content.
DEPLOYING A SELF-SIGNED CERTIFICATE
Replace the fake domain example.com accordingly.
sudo mkdir -p /etc/lighttpd/ssl/example.com cd /etc/lighttpd/ssl/example.com sudo apt install lighttpd-mod-openssl -y sudo lighttpd-enable-mod ssl sudo openssl req -new -x509 -keyout server.pem -out server.pem -days 365 -nodes sudo nano /etc/lighttpd/conf-enabled/10-ssl.conf
# /usr/share/doc/lighttpd/ssl.txt
server.modules += ( "mod_openssl" )
$HTTP["scheme"] == "http" {
$HTTP["host"] =~ ".*" {
url.redirect = (".*" => "https://%0$0")
}
}
$SERVER["socket"] == "0.0.0.0:443" {
ssl.engine = "enable"
ssl.pemfile = "/etc/lighttpd/ssl/domain.com/server.pem"
ssl.cipher-list = "HIGH"
}
sudo lighttpd -t -f /etc/lighttpd/lighttpd.conf && sudo systemctl restart lighttpd.service
ISSUING A FREE PUBLIC CERTIFICATE
Replace the fake domain example.com with a real public domain that has a record that points to the web server.
add-apt-repository ppa:certbot/certbot && sudo apt install certbot -y sudo lighttpd-enable-mod ssl sudo certbot certonly --webroot -w /var/www/html -d example.com -d www.example.com ls -l /etc/letsencrypt/live/example.com sudo nano /etc/lighttpd/lighttpd.conf
# /usr/share/doc/lighttpd/ssl.txt
server.modules += ( "mod_openssl" )
$HTTP["scheme"] == "http" {
$HTTP["host"] =~ ".*" {
url.redirect = (".*" => "https://%0$0")
}
}
$SERVER["socket"] == "0.0.0.0:443" {
ssl.engine = "enable"
ssl.pemfile = "/etc/letsencrypt/live/example.com/fullchain.pem"
ssl.privkey = "/etc/letsencrypt/live/example.com/privkey.pem"
ssl.cipher-list = "HIGH"
}
sudo lighttpd -t -f /etc/lighttpd/lighttpd.conf && sudo systemctl restart lighttpd.service
RENEWING THE PUBLIC CERTIFICATE
Certbot (that used Let’s Encrypt) does not automatically renew he free 90 days public certificates.
Follows the manual renewal command that can be easily scheduled to periodically happens as a cronjob:
sudo certbot renew --force-renewal -d example.com -d www.example.com
BONUS
Reverse proxy for a VHOST:
$HTTP["host"] =~ "(^|.)example.com$" {
proxy.server = ( "" => ( ( "host" => "127.0.0.1", "port" => 8080 ) ) )
}
Reverse proxy for a PATH rewriting the HEADER:
$HTTP["url"] =~ "(^/path)" {
proxy.header = ( "map-urlpath" => ( "/path" => "/") )
proxy.server = ( "" => ( ( "host" => "127.0.0.1", "port" => 8080 ) ) )
}
Another way of creating a self-signed certificate would be:
sudo openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout /etc/ssl/private/apache-selfsigned.key -out /etc/ssl/certs/apache-selfsigned.crt
Note: the different file output format.
REFLECTIONS
Lighttpd is a lightweight web server that’s great for low-resource systems. For better performance and security, it’s a good idea to place it behind a reverse proxy that handles SSL/TLS encryption. Using a CDN like Cloudflare can help protect your site and take care of encrypted connections.
Also, make sure to tighten your firewall settings—only allow the traffic you really need. If you’re using a CDN, restrict access so only the CDN’s IP ranges can connect.
If your site handles sensitive data (like passwords), you should at least use a self-signed certificate to provide basic encryption.