Caddy als Reverse Proxy einrichten: Anfänger-Anleitung mit automatischem HTTPS
Du willst einen Caddy Reverse Proxy einrichten und dabei automatisch gültige HTTPS-Zertifikate von Let's Encrypt bekommen? Diese Schritt-für-Schritt-Anleitung zeigt dir das mit einem minimalen Caddyfile und Docker Compose, ganz ohne Certbot und Cron.

Wenn du einen Caddy Reverse Proxy einrichten möchtest, bekommst du mit wenig Aufwand das, wofür man bei Nginx oder Apache deutlich mehr Handarbeit braucht: einen sauberen Reverse Proxy, der deine internen Dienste hinter einer Domain bündelt und dabei automatisch gültige HTTPS-Zertifikate von Let's Encrypt ausstellt und erneuert. Diese Anleitung richtet sich an Einsteiger sowie an Homeserver- und Selfhosting-Nutzer, die ihre Web-Dienste (etwa eine App auf Port 8080, ein Dashboard oder einen Container) über eine zentrale Stelle erreichbar machen wollen, ohne sich mit Certbot, Cron-Jobs und manueller Zertifikatsverwaltung herumzuschlagen. Am Ende läuft Caddy 2 in Docker, leitet Anfragen auf deine Backends weiter und kümmert sich selbstständig um TLS.
Kurzfassung: Caddy 2 per Docker Compose starten, ein Caddyfile mit Domain und reverse_proxy-Ziel anlegen, Ports 80 und 443 freigeben, DNS auf den Server zeigen lassen. Caddy holt automatisch ein Let's-Encrypt-Zertifikat über die ACME-HTTP-01-Challenge und erzwingt HTTPS, ganz ohne Certbot oder Cron.
Was ist Caddy und warum als Reverse Proxy?
Caddy ist ein moderner Open-Source-Webserver in Go, der vor allem für eine Sache bekannt ist: automatisches HTTPS. Anders als bei klassischen Setups musst du Zertifikate weder manuell beantragen noch erneuern. Caddy spricht das ACME-Protokoll direkt mit Let's Encrypt (oder ZeroSSL), löst die Challenge selbstständig, speichert die Zertifikate und erneuert sie rechtzeitig im Hintergrund. Ein separater Certbot und ein Cron-Job entfallen komplett.
Als Reverse Proxy nimmt Caddy eingehende Anfragen auf den Ports 80/443 entgegen und leitet sie an interne Dienste weiter, etwa an einen Container, der nur auf localhost:8080 lauscht. So liegt deine TLS-Terminierung an einer zentralen Stelle, und deine Backends müssen sich nicht selbst um Zertifikate kümmern.
Reverse Proxy einfach erklärt
Ein Reverse Proxy ist ein Vermittler vor deinen Anwendungen: Der Client (Browser) spricht nur mit Caddy. Caddy entscheidet anhand der angefragten Domain, welches Backend antworten soll, und reicht die Antwort zurück. Das bringt zentrale Vorteile: ein TLS-Endpunkt für alle Dienste, saubere Domains statt Port-Nummern, einfache Erreichbarkeit mehrerer Apps über eine einzige öffentliche IP.
Caddy vs. Nginx
Beide sind exzellente Reverse Proxys. Der Unterschied liegt in der Bedienung: Für einen HTTPS-vHost mit Nginx schreibst du mehrere server-Blöcke, verwaltest Zertifikatspfade und richtest Certbot plus Renewal ein. Bei Caddy genügen pro Dienst zwei, drei Zeilen im Caddyfile, der Rest passiert automatisch. Nginx ist bei sehr großem Traffic und Feintuning weiterhin stark; für Homeserver und übersichtliche Setups ist Caddy oft schneller eingerichtet und wartungsärmer.
Voraussetzungen
- Ein Linux-Server (VPS oder Homeserver) mit öffentlich erreichbarer IP-Adresse.
- Eine eigene Domain (z. B.
example.com) mit Zugriff auf die DNS-Einstellungen. - Docker und Docker Compose installiert (siehe unsere Anleitung zur Docker-Installation).
- Die Ports 80 und 443 müssen von außen erreichbar sein (Firewall/Router/Cloud-Security-Group). Port 80 wird für die ACME-HTTP-01-Challenge benötigt.
- Mindestens ein Backend-Dienst, den du proxen willst (z. B. ein Container oder eine App auf einem internen Port).
Schritt 1: DNS-Eintrag für deine Domain setzen
Bevor Caddy ein Zertifikat ausstellen kann, muss deine Domain auf die öffentliche IP des Servers zeigen. Das ist Voraussetzung für die ACME-Challenge, weil Let's Encrypt prüft, ob du die Domain wirklich kontrollierst.
- Öffne das DNS-Management deines Domain-Anbieters.
- Lege einen A-Record an, der deine (Sub-)Domain auf die IPv4-Adresse des Servers zeigt, z. B.
app.example.com→203.0.113.10. - Optional einen AAAA-Record für IPv6, falls dein Server eine hat.
- Warte, bis die DNS-Änderung propagiert ist. Prüfe das so:
dig +short app.example.com
# Erwartete Ausgabe: die öffentliche IP deines ServersErst wenn hier deine Server-IP zurückkommt, geht es weiter. Sonst schlägt die Zertifikatsausstellung fehl.
Schritt 2: Projektverzeichnis und Caddyfile anlegen
Lege ein Arbeitsverzeichnis an und darin das Caddyfile, die zentrale Konfigurationsdatei von Caddy.
mkdir -p ~/caddy && cd ~/caddy
touch Caddyfile docker-compose.ymlDas Minimal-Caddyfile ist erstaunlich kurz. Du gibst nur die Domain und das Proxy-Ziel an. web:80 ist hier der Name und Port des Backend-Containers (im Beispiel ein Dienst namens web im selben Docker-Netzwerk):
app.example.com {
reverse_proxy web:80
}Mehr braucht es nicht. Caddy aktiviert für app.example.com automatisch HTTPS und richtet einen HTTP-zu-HTTPS-Redirect ein. Wenn dein Backend nicht im selben Compose-Netz läuft, sondern direkt auf dem Host, nutzt du stattdessen die Host-Adresse:
app.example.com {
reverse_proxy 127.0.0.1:8080
}Mehrere Dienste in einem Caddyfile
Du kannst beliebig viele Domains in derselben Datei bündeln. Jeder Block bekommt sein eigenes Zertifikat:
app.example.com {
reverse_proxy web:80
}
dashboard.example.com {
reverse_proxy dashboard:3000
}Schritt 3: Docker-Compose-Datei erstellen
Jetzt definierst du Caddy als Container. Das offizielle Image caddy:latest ist mit rund 50 MB schlank. Wichtig sind die beiden Volumes caddy_data und caddy_config: In caddy_data liegen deine ausgestellten Zertifikate. Persistierst du dieses Volume nicht, holt Caddy nach jedem Neustart neue Zertifikate und läuft in die Rate-Limits von Let's Encrypt.
services:
caddy:
image: caddy:latest
container_name: caddy
restart: unless-stopped
ports:
- "80:80"
- "443:443"
- "443:443/udp"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy_data:/data
- caddy_config:/config
web:
image: nginx:alpine
container_name: web
restart: unless-stopped
volumes:
caddy_data:
caddy_config:Der zusätzliche web-Dienst ist nur ein Beispiel-Backend, damit du sofort testen kannst. In der Praxis ersetzt du ihn durch deine echte Anwendung. Beachte, dass das Backend hier keine Ports nach außen veröffentlicht, es ist nur intern über das Docker-Netzwerk erreichbar. Genau das ist der Sinn des Reverse Proxys.
Schritt 4: Caddy starten und Zertifikat ausstellen lassen
Starte den Stack im Hintergrund:
docker compose up -dBeim ersten Start kontaktiert Caddy Let's Encrypt, beweist über die ACME-HTTP-01-Challenge auf Port 80 die Kontrolle über deine Domain und installiert das Zertifikat. Das dauert meist nur wenige Sekunden. Beobachte den Vorgang in den Logs:
docker compose logs -f caddyAchte auf Zeilen wie certificate obtained successfully. Tauchen Fehler auf, liegt es fast immer an DNS oder einem blockierten Port 80 (siehe Troubleshooting).
Schritt 5: Verifikation und erster Test
Rufe deine Domain im Browser auf: https://app.example.com. Du solltest die Begrüßungsseite des Backends sehen, und das Schloss-Symbol zeigt ein gültiges Zertifikat. Teste zusätzlich auf der Kommandozeile:
- HTTPS-Antwort und Statuscode prüfen:
curl -I https://app.example.com- Den automatischen HTTP-zu-HTTPS-Redirect prüfen:
curl -I http://app.example.com
# Erwartet: HTTP/1.1 308 Permanent Redirect -> Location: https://app.example.com/- Das Zertifikat direkt inspizieren:
echo | openssl s_client -connect app.example.com:443 -servername app.example.com 2>/dev/null | openssl x509 -noout -issuer -datesSteht beim Issuer Let's Encrypt und liegt das Ablaufdatum rund 90 Tage in der Zukunft, ist alles korrekt eingerichtet.
Schritt 6: Konfiguration ändern und neu laden
Wenn du das Caddyfile bearbeitest, musst du Caddy nicht neu starten. Ein Reload übernimmt die Änderung ohne Verbindungsabbruch (Zero-Downtime):
docker exec -w /etc/caddy caddy caddy reloadVor dem Reload lohnt sich ein Syntax-Check, damit ein Tippfehler nicht den laufenden Betrieb stört:
docker exec -w /etc/caddy caddy caddy validateMit caddy fmt --overwrite kannst du das Caddyfile zusätzlich automatisch formatieren lassen.
Updates und Wartung
Caddy erneuert die Zertifikate vollautomatisch, hier musst du nichts tun. Für das Image selbst lohnt sich ein gelegentliches Update:
docker compose pull
docker compose up -dDa das Tag caddy:latest auf die jeweils aktuelle stabile Version zeigt, holt pull die neueste Variante. Wenn du Versionssprünge kontrolliert haben willst, kannst du im Compose-File auch ein festes Major-Tag wie caddy:2 verwenden.
Backup-Hinweis
Sichere unbedingt das Volume caddy_data und dein Caddyfile. In caddy_data liegen deine Zertifikate und die ACME-Account-Daten. Ein einfaches Backup des Volumes:
docker run --rm -v caddy_caddy_data:/data -v "$PWD":/backup alpine \
tar czf /backup/caddy_data_backup.tar.gz -C /data .Den genauen Volume-Namen findest du mit docker volume ls (er wird mit dem Projektnamen als Präfix gebildet).
Troubleshooting
- Zertifikat wird nicht ausgestellt: Prüfe mit
dig +short app.example.com, ob die Domain wirklich auf deine Server-IP zeigt. Stimmt der DNS-Eintrag nicht, scheitert die Challenge. - Port 80 blockiert: Die HTTP-01-Challenge braucht Port 80 von außen. Öffne ihn in Firewall, Router und ggf. Cloud-Security-Group. Stelle sicher, dass kein anderer Dienst Port 80 belegt.
- 502 Bad Gateway: Caddy erreicht das Backend nicht. Prüfe, ob der Ziel-Container läuft (
docker compose ps) und ob Name und Port imreverse_proxystimmen. Bei Containern im selben Netz nutzt du den Service-Namen, nichtlocalhost. - Rate-Limit von Let's Encrypt: Hast du oft neu gestartet und das
caddy_data-Volume nicht persistiert, kannst du temporär gesperrt sein. Persistiere das Volume und teste Konfigurationen vorab gegen die Staging-Umgebung mit der Direktiveacme_ca https://acme-staging-v02.api.letsencrypt.org/directoryim Global-Block. - Lokal testen ohne öffentliche Domain: Für reine Tests stellt Caddy bei
localhostautomatisch ein eigenes, intern vertrauenswürdiges Zertifikat aus, ganz ohne Let's Encrypt.
Häufige Fragen
Brauche ich Certbot oder einen Cron-Job für die Zertifikate?
Nein. Caddy übernimmt die komplette Zertifikatsverwaltung selbst: Es beantragt das Zertifikat über ACME bei Let's Encrypt, speichert es im Volume und erneuert es automatisch, bevor es abläuft. Ein separater Certbot und ein Cron-Job sind nicht nötig.
Welche Ports muss ich öffnen?
Port 80 und Port 443 müssen von außen erreichbar sein. Port 443 dient dem eigentlichen HTTPS-Verkehr, Port 80 wird für die ACME-HTTP-01-Challenge sowie für den automatischen Redirect auf HTTPS benötigt. Backends bleiben intern und brauchen keine offenen Ports nach außen.
Wie groß ist das Caddy-Docker-Image?
Das offizielle Image caddy:latest ist mit rund 50 MB sehr schlank, da Caddy als einzelne, statisch gelinkte Go-Binary ausgeliefert wird. Das macht Caddy ressourcensparend und ideal für Homeserver.
Kann ich mehrere Dienste über einen Caddy proxen?
Ja. Du legst pro Domain bzw. Subdomain einen eigenen Block im Caddyfile an und gibst jeweils das passende reverse_proxy-Ziel an. Caddy verwaltet für jede Domain ein eigenes Zertifikat automatisch.
Caddy oder Nginx: Was nehme ich als Einsteiger?
Für die meisten Selfhosting- und Homeserver-Szenarien ist Caddy der einfachere Einstieg, weil HTTPS automatisch funktioniert und das Caddyfile sehr kompakt ist. Nginx bietet mehr Feintuning bei sehr hoher Last und speziellen Anforderungen, verlangt aber mehr Konfigurationsaufwand und eine separate Zertifikatslösung.
Fazit
Einen Caddy Reverse Proxy einrichten ist in wenigen Minuten erledigt: DNS setzen, ein kurzes Caddyfile schreiben, Docker Compose starten, fertig. Das automatische HTTPS von Let's Encrypt nimmt dir den lästigsten Teil ab, denn Zertifikate werden ohne Certbot und Cron beantragt und erneuert. Damit hast du eine wartungsarme, zentrale Stelle für all deine selbstgehosteten Dienste, hinter sauberen Domains und gültigem TLS.
Weiterführende Anleitungen und Quellen
Wenn dir noch die Container-Basis fehlt, hilft dir unsere Schritt-für-Schritt-Anleitung zur Docker-Installation beim Einstieg. Betreibst du deinen Reverse Proxy in der Cloud, ist auch unser Beitrag zur AWS European Sovereign Cloud mit neuen EC2-G6-Instanzen interessant, etwa als Hosting-Grundlage. Weitere Tutorials findest du in der Kategorie Cloud.
Quellen: Caddy Documentation – Reverse Proxy Quick-start, Caddy Documentation – Automatic HTTPS und Caddy auf Docker Hub.