Caddy-webserver installeren met automatische HTTPS
Caddy op Ubuntu installeren vanuit de officiële repository, een Caddyfile schrijven voor statische sites en reverse proxies, automatische certificaten, systemd, logs en veelgemaakte fouten bij migratie vanaf Nginx begrijpen.

Caddy is een webserver die TLS-certificaten standaard ophaalt en vernieuwt. Voor een kleine VPS met één of twee domeinen verdwijnt daarmee een hele klasse Certbot-timers en Nginx-snippetbestanden. De configuratietaal (Caddyfile) is kort. Reverse proxy, gzip en HTTP/2 zijn normale functies, geen weekend extra modules.
Nginx blijft voor sommige teams de juiste keuze: jullie hebben al beproefde configs, of jullie hebben een heel specifiek module nodig. Deze gids is voor het andere veelvoorkomende geval — je wilt HTTPS dat werkt op een verse Hiddence-VPS zonder include-snippets uit je hoofd te leren. We installeren Caddy vanuit de officiële apt-repo, leggen uit hoe het met Let's Encrypt praat, serveren een statische site, proxyn een lokale app, hosten meerdere domeinen, kijken naar logs en behandelen de gebruikelijke gevechten om poort 80 met Apache of een oude Nginx.
Wanneer Caddy goed past
Automatische HTTPS is de kop, maar de dagelijkse winst is minder bewegende onderdelen. Caddy luistert op 80 en 443, stuurt HTTP door naar HTTPS en bewaart certificaten in zijn datamap. Je hebt nog steeds een domein nodig dat naar de VPS wijst. Je mag ACME nog steeds niet stukmaken (firewall 80/tcp, geen ander proces dat :80 steelt). Wildcardcertificaten hebben een DNS-providermodule nodig — dat is een langer pad dan een certificaat voor één host.
- Automatische HTTP→HTTPS-omleiding en certificaatvernieuwing
- Leesbare Caddyfile in plaats van lange serverblokken
- Capabele reverse proxy voor Node, Python, PHP-FPM via extra config, of Docker-backends
- HTTP/2 en moderne TLS-standaarden zonder een cijfer-spreadsheet
- systemd-unit uit het officiële pakket
Vereisten
Een domein moet naar deze VPS resolven voordat Caddy ACME HTTP-01 kan bewijzen. Als DNS nog propageert, faalt Caddy bij uitgifte en probeert het opnieuw; dat lijkt op «Caddy is stuk» terwijl het alleen DNS is. Stop Apache of Nginx eerst als zij 80/443 bezitten.
- Ubuntu 22.04 of 24.04
- Een domein-A-record naar het VPS-IP (en AAAA als je IPv6 gebruikt)
- Poorten 80 en 443 vrij en toegestaan in de firewall
- Root of sudo
Stap 1: Caddy installeren vanuit de officiële repository
Installeer geen willekeurige oude Caddy uit Ubuntu Universe als je actueel TLS- en ACME-gedrag wilt. Het Caddy-project documenteert een apt-bron. Na installatie bestaat de gebruiker caddy en is de service ingeschakeld.
ssh root@YOUR_VPS_IP
apt update && apt -y install debian-keyring debian-archive-keyring apt-transport-https curl gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | tee /etc/apt/sources.list.d/caddy-stable.list
apt update
apt -y install caddy
caddy version
systemctl status caddy --no-pagerStap 2: Eerste Caddyfile — statische site
De standaard-Caddyfile is /etc/caddy/Caddyfile. Vervang die door je domein. Caddy probeert een certificaat te halen zodra de config laadt als de hostnaam niet localhost is. Zet sitebestanden in een map die de gebruiker caddy kan lezen (vaak www-data-achtige rechten, maar het pakket gebruikt gebruiker caddy).
mkdir -p /var/www/example
echo '<h1>It works</h1>' > /var/www/example/index.html
chown -R caddy:caddy /var/www/example
cat >/etc/caddy/Caddyfile <<'EOF'
example.com {
root * /var/www/example
file_server
encode gzip
}
EOF
caddy validate --config /etc/caddy/Caddyfile
systemctl reload caddy
# Watch issuance:
journalctl -u caddy -fStap 3: Reverse proxy van een lokale toepassing
Als Gunicorn, Node of Docker op 127.0.0.1:8000 luistert, moet Caddy het enige openbare proces zijn. De reverse_proxy-richtlijn stuurt Host en X-Forwarded-*-headers op een verstandige manier door voor de meeste apps. Als de app absolute HTTP-URL’s genereert, zet de trusted-proxy- / HTTPS-vlaggen in de app (Django SECURE_PROXY_SSL_HEADER, Express trust proxy, enzovoort).
app.example.com {
encode gzip
reverse_proxy 127.0.0.1:8000
}
# Several hosts in one file are normal:
# blog.example.com {
# root * /var/www/blog
# file_server
# }Stap 4: Firewall en systemd
Sta 80 en 443 toe. De unit van Caddy is caddy.service; een reload volstaat na Caddyfile-wijzigingen als het proces gezond is. Wijzig je omgevingsvariabelen voor een DNS-plugin, dan is een volledige herstart duidelijker. Certificaten staan standaard onder /var/lib/caddy/.local/share/caddy/ — neem dat pad op in back-ups als je om ratelimits bij een herinstallatie geeft.
ufw allow OpenSSH
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable
systemctl enable --now caddy
systemctl reload caddy
# Backup cert storage (path may vary slightly by version):
ls -la /var/lib/caddy/Stap 5: Logs, compressie en headers
Toegangslogs helpen als een bot een pad hamert of als je 404’s debugt. Je kunt per site loggen. Voeg beveiligingsheaders toe als je een browserapp host; kopieer geen enorm headerpakket zonder HSTS te begrijpen (een lange max-age onthouden browsers).
example.com {
root * /var/www/example
file_server
encode gzip
log {
output file /var/log/caddy/example.log
}
header {
X-Content-Type-Options nosniff
Referrer-Policy no-referrer-when-downgrade
-Server
}
}
mkdir -p /var/log/caddy
chown caddy:caddy /var/log/caddy
systemctl reload caddyStap 6: PHP en andere extras
Caddy kan met PHP-FPM praten via de php_fastcgi-richtlijn. Dat is genoeg voor veel WordPress- of Laravel-hosts, maar je hebt nog steeds php-fpm geïnstalleerd nodig en een socketpad dat klopt. Heb je al een perfecte Nginx-PHP-config, dan is migreren op één avond optioneel — Caddy schittert meer op reverse proxy + statisch + automatische TLS.
example.com {
root * /var/www/example
php_fastcgi unix//run/php/php8.3-fpm.sock
file_server
}
# Confirm FPM is running:
systemctl status php8.3-fpmMigreren vanaf Nginx zonder downtimesurprises
Stop Nginx voordat je Caddy start, anders vechten ze om 80/443. Verlaag de DNS-TTL de dag ervoor als je ook IP’s verhuist. Test met curl --resolve zodat je de nieuwe VPS raakt voordat je het A-record omzet. Bewaar Nginx-configs een week in git voor het geval je moet terugrollen.
- systemctl stop nginx && systemctl disable nginx
- Caddy installeren, Caddyfile valideren, Caddy starten
- curl -I --resolve example.com:443:NEW_IP https://example.com
- Pas daarna DNS aan als het IP nieuw is
- Heruitgifte is automatisch; laat Certbot niet ook tegen dezelfde hostnaam lopen
Problemen oplossen
ACME-fouten zijn bijna altijd DNS, firewall of een andere dienst op poort 80. Caddy-logregels noemen tls.obtain. Werkt de site op HTTP maar niet op HTTPS, dan is uitgifte nooit afgerond. Zie je te veel certificaten, dan heb je Let's Encrypt-ratelimits geraakt — gebruik de staging-CA tijdens testen, niet productie.
- validate faalt: Caddyfile-syntax, ontbrekende accolade
- permission denied op root: chown caddy voor de sitemap
- bind: address already in use — ss -tulpn | grep -E ':80|:443'
- certificaattime-out: dig +short het domein vanaf de VPS, ufw allow 80
- 502 reverse_proxy: backend down, of je proxiede naar localhost vanaf een containernetwerk op de verkeerde manier
Beveiligingsnotities
De TLS-standaarden van Caddy zijn conservatief. Jouw werk is applicatiebeveiliging en SSH. Zet de Caddy-beheer-API niet aan op een openbare interface. Het standaard beheereindpunt is lokaal; laat het zo. Gebruik je een Caddyfile van internet, lees dan elke matcher — een snippet die /* reverse_proxyt naar een intern IP kan een open proxy worden.
- Stel de beheer-API niet bloot
- Houd het pakket bijgewerkt
- HSTS alleen als je zeker weet dat HTTPS voor alle hostnamen werkt
- Scheid test- en productiehostnamen om ACME-ratelimits te beschermen
Tips
- caddy fmt --overwrite /etc/caddy/Caddyfile houdt het bestand leesbaar
- Gebruik import-snippets als je veel vergelijkbare sites hebt
- Voor Docker is het image caddy:alpine met een gemounte Caddyfile gebruikelijk
- Wildcardcerts hebben een DNS-module en API-token nodig — bescherm dat token
- Lees journalctl -u caddy voordat je het hele bestand herschrijft
Caddy op een VPS is: officieel pakket, een korte Caddyfile, poorten 80/443 open, DNS al naar de server wijzend, en systemd-reload na wijzigingen. Gebruik het als statische bestandsserver of als reverse proxy voor Gunicorn, Node of Docker. Automatische HTTPS werkt als ACME op poort 80 kan antwoorden; faalt de uitgifte, los DNS en poortconflicten op voordat je Caddy de schuld geeft. Maak een back-up van /var/lib/caddy als je vaak opnieuw installeert.