Caddy-Webserver mit automatischem HTTPS installieren
Caddy auf Ubuntu aus dem offiziellen Repository installieren, eine Caddyfile für statische Sites und Reverse-Proxys schreiben, automatische Zertifikate, systemd, Logs und typische Fehler beim Umstieg von Nginx verstehen.

Caddy ist ein Webserver, der TLS-Zertifikate standardmäßig holt und erneuert. Für einen kleinen VPS mit ein oder zwei Domains entfällt damit eine ganze Klasse von Certbot-Timern und Nginx-Snippet-Dateien. Die Konfigurationssprache (Caddyfile) ist kurz. Reverse-Proxy, gzip und HTTP/2 sind normale Funktionen, kein Wochenende extra Module.
Nginx bleibt für manche Teams richtig: Sie haben bewährte Configs oder brauchen ein sehr spezielles Modul. Diese Anleitung gilt für den anderen häufigen Fall — Sie wollen HTTPS, das auf einem frischen Hiddence-VPS funktioniert, ohne Include-Snippets auswendig zu lernen. Wir installieren Caddy aus dem offiziellen apt-Repo, erklären, wie es mit Let's Encrypt spricht, dienen eine statische Site aus, proxyn eine lokale App, hosten mehrere Domains, schauen in Logs und behandeln die üblichen Kämpfe um Port 80 mit Apache oder einem alten Nginx.
Wann Caddy gut passt
Automatisches HTTPS ist die Überschrift, der Alltagssieg sind weniger bewegliche Teile. Caddy lauscht auf 80 und 443, leitet HTTP nach HTTPS um und speichert Zertifikate in seinem Datenverzeichnis. Sie brauchen weiter eine Domain, die auf den VPS zeigt. Sie dürfen ACME nicht kaputtmachen (Firewall 80/tcp, kein anderer Prozess klaut :80). Wildcard-Zertifikate brauchen ein DNS-Provider-Modul — das ist ein längerer Weg als ein Einzelhost-Zertifikat.
- Automatische HTTP→HTTPS-Umleitung und Zertifikatserneuerung
- Lesbare Caddyfile statt langer Server-Blöcke
- Fähiger Reverse-Proxy für Node, Python, PHP-FPM per Zusatzconfig oder Docker-Backends
- HTTP/2 und moderne TLS-Defaults ohne Cipher-Spreadsheet
- systemd-Unit aus dem offiziellen Paket
Voraussetzungen
Eine Domain muss auf diesen VPS auflösen, bevor Caddy ACME HTTP-01 beweisen kann. Läuft DNS noch nach, schlägt die Ausstellung fehl und Caddy versucht es erneut; das wirkt wie „Caddy ist kaputt“, ist aber nur DNS. Apache oder Nginx zuerst stoppen, wenn sie 80/443 besitzen.
- Ubuntu 22.04 oder 24.04
- Ein Domain-A-Record auf die VPS-IP (und AAAA bei IPv6)
- Ports 80 und 443 frei und in der Firewall erlaubt
- Root oder sudo
Schritt 1: Caddy aus dem offiziellen Repository installieren
Installieren Sie kein zufälliges altes Caddy aus Ubuntu Universe, wenn Sie aktuelles TLS- und ACME-Verhalten wollen. Das Caddy-Projekt dokumentiert eine apt-Quelle. Nach der Installation existiert der Benutzer caddy und der Dienst ist aktiviert.
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-pagerSchritt 2: Erste Caddyfile — statische Site
Die Standard-Caddyfile liegt unter /etc/caddy/Caddyfile. Ersetzen Sie sie durch Ihre Domain. Caddy versucht ein Zertifikat, sobald die Config lädt, sofern der Hostname nicht localhost ist. Site-Dateien in ein Verzeichnis legen, das der Benutzer caddy lesen kann (oft www-data-ähnliche Rechte, das Paket nutzt aber den Benutzer 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 -fSchritt 3: Lokale Anwendung per Reverse-Proxy
Wenn Gunicorn, Node oder Docker auf 127.0.0.1:8000 lauscht, sollte Caddy der einzige öffentliche Prozess sein. Die Direktive reverse_proxy leitet Host und X-Forwarded-*-Header für die meisten Apps sinnvoll weiter. Erzeugt die App absolute HTTP-URLs, setzen Sie Trusted-Proxy- / HTTPS-Flags in der App (Django SECURE_PROXY_SSL_HEADER, Express trust proxy und so weiter).
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
# }Schritt 4: Firewall und systemd
80 und 443 erlauben. Caddys Unit ist caddy.service; nach Caddyfile-Änderungen reicht ein Reload, wenn der Prozess gesund ist. Ändern Sie Umgebungsvariablen für ein DNS-Plugin, ist ein voller Restart klarer. Zertifikate liegen standardmäßig unter /var/lib/caddy/.local/share/caddy/ — diesen Pfad in Backups aufnehmen, wenn Ihnen Rate-Limits bei einer Neuinstallation wichtig sind.
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/Schritt 5: Logs, Kompression und Header
Access-Logs helfen, wenn ein Bot einen Pfad hämmert oder Sie 404er debuggen. Sie können pro Site loggen. Security-Header setzen, wenn Sie eine Browser-App hosten; kein riesiges Header-Paket kopieren, ohne HSTS zu verstehen (ein langes max-age merken sich Browser dauerhaft).
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 caddySchritt 6: PHP und weitere Extras
Caddy spricht mit PHP-FPM über die Direktive php_fastcgi. Das reicht für viele WordPress- oder Laravel-Hosts, Sie brauchen aber weiterhin installiertes php-fpm und einen passenden Socket-Pfad. Haben Sie schon eine perfekte Nginx-PHP-Config, ist die Migration an einem Abend optional — Caddy glänzt stärker bei Reverse-Proxy plus statisch plus automatischem 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-fpmVon Nginx umziehen, ohne Downtime-Überraschungen
Nginx stoppen, bevor Caddy startet, sonst kämpfen sie um 80/443. DNS-TTL am Vortag senken, wenn Sie auch IPs wechseln. Mit curl --resolve testen, damit Sie den neuen VPS treffen, bevor der A-Record umschwenkt. Nginx-Configs eine Woche in Git behalten, falls Sie zurückmüssen.
- systemctl stop nginx && systemctl disable nginx
- Caddy installieren, Caddyfile validieren, Caddy starten
- curl -I --resolve example.com:443:NEW_IP https://example.com
- DNS erst ändern, wenn die IP neu ist
- Neuausstellung ist automatisch; Certbot nicht zusätzlich gegen denselben Hostnamen laufen lassen
Fehlerbehebung
ACME-Fehler sind fast immer DNS, Firewall oder ein anderer Dienst auf Port 80. Caddy-Logzeilen erwähnen tls.obtain. Funktioniert die Site per HTTP, aber nicht HTTPS, ist die Ausstellung nie durchgelaufen. Sehen Sie zu viele Zertifikate, haben Sie Let's-Encrypt-Rate-Limits getroffen — zum Testen die Staging-CA nutzen, nicht Produktion.
- validate schlägt fehl: Caddyfile-Syntax, fehlende Klammer
- permission denied auf root: chown caddy für das Site-Verzeichnis
- bind: address already in use — ss -tulpn | grep -E ':80|:443'
- Zertifikats-Timeout: dig +short der Domain vom VPS, ufw allow 80
- 502 reverse_proxy: Backend down, oder falsch auf localhost aus einem Container-Netz geproxyt
Sicherheitshinweise
Caddys TLS-Defaults sind konservativ. Ihre Aufgabe sind Anwendungssicherheit und SSH. Die Caddy-Admin-API nicht auf einer öffentlichen Schnittstelle aktivieren. Der Standard-Admin-Endpunkt ist lokal; so belassen. Wenn Sie eine Caddyfile aus dem Internet nutzen, jeden Matcher lesen — ein Snippet, das /* auf eine interne IP reverse_proxied, kann zum offenen Proxy werden.
- Admin-API nicht öffentlich machen
- Paket aktuell halten
- HSTS erst, wenn HTTPS für alle Hostnamen sicher funktioniert
- Test- und Produktionshostnamen trennen, um ACME-Rate-Limits zu schützen
Tipps
- caddy fmt --overwrite /etc/caddy/Caddyfile hält die Datei lesbar
- Import-Snippets nutzen, wenn Sie viele ähnliche Sites haben
- Für Docker ist das Image caddy:alpine mit gemounteter Caddyfile üblich
- Wildcard-Zerts brauchen ein DNS-Modul und API-Token — das Token schützen
- journalctl -u caddy lesen, bevor Sie die ganze Datei umschreiben
Caddy auf einem VPS heißt: offizielles Paket, kurze Caddyfile, Ports 80/443 offen, DNS zeigt schon auf den Server, systemd-Reload nach Änderungen. Nutzen Sie es als statischen Dateiserver oder als Reverse-Proxy vor Gunicorn, Node oder Docker. Automatisches HTTPS funktioniert, wenn ACME auf Port 80 antworten kann; schlägt die Ausstellung fehl, DNS und Portkonflikte beheben, bevor Sie Caddy die Schuld geben. /var/lib/caddy sichern, wenn Sie oft neu installieren.