Docker-Container handhaben SSL typischerweise nicht selbst — ein Reverse Proxy davor terminiert TLS und leitet den entschlüsselten Traffic an den Container weiter. Diese Anleitung behandelt die drei gängigsten Ansätze.
Ansatz 1: Nginx Reverse Proxy mit manuellem Zertifikat
Der einfachste Ansatz für kleine Deployments. Holen Sie sich ein Zertifikat von GetHTTPS und mounten Sie es in einen Nginx-Container.
docker-compose.yml
services:
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
- ./certs/fullchain.pem:/etc/ssl/fullchain.pem:ro
- ./certs/privkey.pem:/etc/ssl/privkey.pem:ro
depends_on:
- app
app:
image: your-app:latest
expose:
- "3000"
nginx.conf
server {
listen 443 ssl http2;
server_name yourdomain.com;
ssl_certificate /etc/ssl/fullchain.pem;
ssl_certificate_key /etc/ssl/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
location / {
proxy_pass http://app:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
server {
listen 80;
server_name yourdomain.com;
return 301 https://$host$request_uri;
}
Zur Erneuerung: Ersetzen Sie die Dateien in ./certs/ mit neuen von GetHTTPS, dann docker compose exec nginx nginx -s reload.
Ansatz 2: Traefik mit automatischem Let’s Encrypt
Traefik ist ein Reverse Proxy, der für Container entwickelt wurde. Er kann automatisch Let’s Encrypt-Zertifikate beziehen und erneuern.
docker-compose.yml
services:
traefik:
image: traefik:v3.0
command:
- "--providers.docker=true"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.letsencrypt.acme.email=you@example.com"
- "--certificatesresolvers.letsencrypt.acme.storage=/acme/acme.json"
- "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- traefik-acme:/acme
app:
image: your-app:latest
labels:
- "traefik.http.routers.app.rule=Host(`yourdomain.com`)"
- "traefik.http.routers.app.tls.certresolver=letsencrypt"
- "traefik.http.services.app.loadbalancer.server.port=3000"
volumes:
traefik-acme:
Traefik erledigt alles: Zertifikatsausstellung, Erneuerung und HTTPS-Terminierung. Kein manuelles Zertifikatsmanagement erforderlich.
Ansatz 3: Caddy (Zero-Config HTTPS)
Caddy bezieht und erneuert Let’s Encrypt-Zertifikate automatisch ohne Konfiguration.
docker-compose.yml
services:
caddy:
image: caddy:2
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy-data:/data
depends_on:
- app
app:
image: your-app:latest
expose:
- "3000"
volumes:
caddy-data:
Caddyfile
yourdomain.com {
reverse_proxy app:3000
}
Das ist die gesamte Konfiguration. Caddy holt ein Let’s Encrypt-Zertifikat und erneuert es automatisch.
Welchen Ansatz wählen?
| Nginx + manuelles Zert. | Traefik | Caddy | |
|---|---|---|---|
| Einrichtung | Mittel (Konfig + Zertifikatsdateien) | Mittel (Labels) | Minimal |
| Automatische Erneuerung | ❌ (manuell) | ✅ | ✅ |
| Flexibilität | Hoch | Hoch | Mittel |
| Lernkurve | Niedrig (vertraut) | Mittel | Niedrig |
| Am besten für | Kleine Deployments, volle Kontrolle | Dynamische Container, Microservices | Einfache Websites, minimale Konfig |
Zertifikate in Docker erneuern
Ansatz 1 (Nginx + manuell):
# Zertifikatsdateien in Ihrem lokalen ./certs/-Verzeichnis ersetzen
cp new-fullchain.pem ./certs/fullchain.pem
cp new-privkey.pem ./certs/privkey.pem
# Nginx im Container neu laden (kein Neustart nötig)
docker compose exec nginx nginx -s reload
Ansatz 2 (Traefik) & 3 (Caddy):
Automatisch — sie handhaben die Erneuerung intern. Zertifikate werden in Docker-Volumes (traefik-acme oder caddy-data) gespeichert und bleiben über Container-Neustarts hinweg erhalten.
Docker Swarm: Secrets verwenden
Für Docker-Swarm-Deployments verwenden Sie Docker Secrets statt Bind-Mounting von Zertifikatsdateien:
# Secrets aus Ihren Zertifikatsdateien erstellen
docker secret create ssl_cert fullchain.pem
docker secret create ssl_key privkey.pem
# In docker-compose.yml (Deploy-Modus)
services:
nginx:
image: nginx:alpine
secrets:
- ssl_cert
- ssl_key
configs:
- source: nginx_conf
target: /etc/nginx/conf.d/default.conf
secrets:
ssl_cert:
external: true
ssl_key:
external: true
Secrets werden unter /run/secrets/ssl_cert und /run/secrets/ssl_key im Container gemountet — im Ruhezustand und bei der Übertragung verschlüsselt.
Häufige Fehler
Zertifikate in Docker-Images einbacken
# ❌ NIEMALS so machen
COPY fullchain.pem /etc/ssl/fullchain.pem
COPY privkey.pem /etc/ssl/privkey.pem
Zertifikate laufen alle 90 Tage ab. Sie in das Image einzubacken bedeutet, alle 60 Tage neu zu bauen und bereitzustellen. Mounten Sie Zertifikate immer als Volumes oder Secrets.
Vergessen, Port 80 freizugeben
Port 80 wird benötigt für:
- HTTP → HTTPS-Weiterleitung
- Let’s Encrypt HTTP-01-Challenge (für automatische Erneuerung bei Traefik/Caddy)
ports:
- "80:80" # Das nicht vergessen
- "443:443"
ACME-Daten nicht persistieren
Traefik und Caddy speichern ihre Let’s Encrypt-Zertifikate und Account-Schlüssel in Volumes. Ohne Persistenz fordern sie bei jedem Container-Neustart neue Zertifikate an — und werden auf Rate-Limits stoßen:
volumes:
traefik-acme: # MUSS ein benanntes Volume sein, kein anonymes
caddy-data:
Häufig gestellte Fragen
Kann mein App-Container SSL direkt handhaben?
Das ist möglich, wird aber nicht empfohlen. Das Reverse-Proxy-Muster (TLS am Edge terminieren, intern unverschlüsseltes HTTP weiterleiten) ist Standard, weil: die App nichts über Zertifikate wissen muss, Erneuerungen keine App-Neustarts erfordern und die TLS-Konfiguration zentralisiert ist.
Wie handhabe ich SSL für mehrere Container?
Mit Traefik oder Caddy fügen Sie Labels/Konfigurationen für jeden Service hinzu — sie erhalten automatisch separate Zertifikate. Mit Nginx fügen Sie mehrere server-Blöcke in der Konfiguration hinzu.
Sollte ich GetHTTPS oder Traefiks eingebautes ACME verwenden?
Verwenden Sie Traefik/Caddys eingebautes ACME für die Produktion — es handhabt die Erneuerung automatisch. Verwenden Sie GetHTTPS, wenn Sie ein Zertifikat für den Nginx-Reverse-Proxy-Ansatz (Ansatz 1) benötigen oder für Umgebungen, in denen der Container keinen direkten Internetzugang für ACME-Challenges hat.
Wie mounte ich Zertifikate sicher in Docker?
Mounten Sie als schreibgeschützt (:ro), verwenden Sie Docker Secrets für den privaten Schlüssel im Swarm-Modus und stellen Sie sicher, dass nur der Reverse-Proxy-Container Zugriff auf die Zertifikatsdateien hat. Backen Sie Zertifikate niemals in ein Docker-Image ein — sie laufen ab und Sie müssten neu bauen.
Kann ich GetHTTPS-Zertifikate mit Kubernetes verwenden?
Ja. Erstellen Sie ein Kubernetes TLS Secret aus Ihren GetHTTPS-Zertifikatsdateien:
kubectl create secret tls my-tls-cert --cert=fullchain.pem --key=privkey.pem
Referenzieren Sie es dann in Ihrer Ingress-Ressource. Für automatisierte Erneuerung in Kubernetes verwenden Sie cert-manager mit einem Let’s Encrypt ClusterIssuer.