Zum Hauptinhalt springen
S-EDV news
← Alle Anleitungen
📘 Anleitung Cloud / Hosting 01.06.2026 · 8 min Lesezeit

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.

Ein minimalistisches Glasprisma, das Datenströme sortiert und mit leuchtend mintgrünen Vorhängeschlössern versieht, als Symbol für die automatische HTTPS-Verschlüsselung des Caddy Reverse Proxys.

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

  1. Ein Linux-Server (VPS oder Homeserver) mit öffentlich erreichbarer IP-Adresse.
  2. Eine eigene Domain (z. B. example.com) mit Zugriff auf die DNS-Einstellungen.
  3. Docker und Docker Compose installiert (siehe unsere Anleitung zur Docker-Installation).
  4. 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.
  5. 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.

  1. Öffne das DNS-Management deines Domain-Anbieters.
  2. Lege einen A-Record an, der deine (Sub-)Domain auf die IPv4-Adresse des Servers zeigt, z. B. app.example.com203.0.113.10.
  3. Optional einen AAAA-Record für IPv6, falls dein Server eine hat.
  4. Warte, bis die DNS-Änderung propagiert ist. Prüfe das so:
dig +short app.example.com
# Erwartete Ausgabe: die öffentliche IP deines Servers

Erst 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.yml

Das 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 -d

Beim 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 caddy

Achte 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:

  1. HTTPS-Antwort und Statuscode prüfen:
curl -I https://app.example.com
  1. 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/
  1. Das Zertifikat direkt inspizieren:
echo | openssl s_client -connect app.example.com:443 -servername app.example.com 2>/dev/null | openssl x509 -noout -issuer -dates

Steht 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 reload

Vor dem Reload lohnt sich ein Syntax-Check, damit ein Tippfehler nicht den laufenden Betrieb stört:

docker exec -w /etc/caddy caddy caddy validate

Mit 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 -d

Da 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

  1. 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.
  2. 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.
  3. 502 Bad Gateway: Caddy erreicht das Backend nicht. Prüfe, ob der Ziel-Container läuft (docker compose ps) und ob Name und Port im reverse_proxy stimmen. Bei Containern im selben Netz nutzt du den Service-Namen, nicht localhost.
  4. 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 Direktive acme_ca https://acme-staging-v02.api.letsencrypt.org/directory im Global-Block.
  5. Lokal testen ohne öffentliche Domain: Für reine Tests stellt Caddy bei localhost automatisch 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.