Traefik ist dafür bekannt, Zertifikate automatisch über ACME auszustellen. Aber manchmal müssen Sie stattdessen Ihr eigenes Zertifikat verwenden — eines, das von GetHTTPS ausgestellt wurde, eine unternehmensinterne CA oder ein Wildcard-Zertifikat, das Sie an anderer Stelle verwalten. Diese Anleitung zeigt Ihnen genau, wie das mit Traefik v3 funktioniert.
Das Wichtigste, das Sie von Anfang an verstehen müssen: Sie können eine Zertifikatsdatei nicht über ein Docker-Label anhängen. Traefik-Labels steuern das Routing und aktivieren TLS, aber das Zertifikat selbst muss über den File-Provider als dynamische Konfiguration bereitgestellt werden. Daran scheitern beim ersten Mal fast alle. Wir machen es auf die richtige Weise.
Wenn Sie noch kein Zertifikat haben, holen Sie sich in 5 Minuten ein kostenloses.
Wann sollten Sie das verwenden (gegenüber dem automatischen ACME von Traefik)
| Automatisches ACME verwenden (Let’s Encrypt) | Eigenes Zertifikat verwenden (diese Anleitung) |
|---|---|
| Öffentliche Website, aus dem Internet erreichbar | Interner/Intranet-Dienst (kein öffentliches DNS) |
| Ein Standard-DV-Zertifikat ist ausreichend | Sie benötigen eine bestimmte CA, ein Wildcard- oder ein OV-/EV-Zertifikat |
| Traefik kann die HTTP-/DNS-Challenge abschließen | Air-Gapped oder durch eine Firewall geschützter Host |
| Sie wünschen sich null Zertifikatsverwaltung | Sie haben bereits ein Zertifikat von GetHTTPS oder anderswo |
Wenn das automatische ACME zu Ihrem Anwendungsfall passt, ist der certificatesResolvers von Traefik einfacher. Diese Anleitung ist für den Fall „Ich habe bereits fullchain.pem + privkey.pem und brauche Traefik, um sie auszuliefern”.
Voraussetzungen
- Traefik v3, das als Docker-Container läuft (die Konfiguration unten verwendet Docker, aber der Teil zur dynamischen Konfiguration gilt für jedes Setup)
- Ihre Zertifikatsdateien — zwei davon:
fullchain.pem— Ihr Zertifikat + die Zwischenzertifikats-Ketteprivkey.pem— Ihr privater Schlüssel
- Eine Domain, die auf den Host zeigt (oder ein lokaler Eintrag in der Hosts-Datei für die interne Nutzung)
Welche Dateien benötigt Traefik? Traefik möchte die vollständige Kette in
certFileund den Schlüssel inkeyFile. Wenn Sie eine reine Leaf-Dateicert.pemverwenden, erhalten Clients Fehler wegen „unvollständiger Kette” — Traefik hängt bei File-Provider-Zertifikaten keine Zwischenzertifikate automatisch an. Verwenden Siefullchain.pem. Zertifikatsformate erklärt →
Wie die Konfiguration von Traefik aufgeteilt ist
Traefik hat zwei Arten von Konfiguration, und Zertifikate liegen in der zweiten:
- Statische Konfiguration — wird beim Start festgelegt (Entrypoints, Provider). Eine Änderung erfordert einen Neustart. Diese gehört in
traefik.ymloder in die Befehls-Flags des Containers. - Dynamische Konfiguration — wird ohne Neustart live neu geladen (Router, Services, TLS-Zertifikate). Das ist es, was der File-Provider einliest.
Ihr Zertifikat ist dynamische Konfiguration. Deshalb kann ein Label es nicht tragen — Labels werden vom Docker-Provider eingelesen, aber tls.certificates ist ein Konzept des File-Providers.
Schritt 1: Die Zertifikatsdateien ablegen
Legen Sie die Dateien in einem Verzeichnis ab, das Sie in den Container einbinden:
mkdir -p ./traefik/certs
cp fullchain.pem ./traefik/certs/
cp privkey.pem ./traefik/certs/
# Den privaten Schlüssel absichern
chmod 600 ./traefik/certs/privkey.pem
chmod 644 ./traefik/certs/fullchain.pem
Schritt 2: Die dynamische Konfiguration schreiben
Erstellen Sie ./traefik/dynamic/certs.yml. Hier deklarieren Sie Ihr Zertifikat:
# ./traefik/dynamic/certs.yml (dynamische Konfiguration — File-Provider)
tls:
certificates:
- certFile: /certs/fullchain.pem
keyFile: /certs/privkey.pem
# Optional: dieses Zertifikat zum Standard für jeden Host machen, der
# nicht zu einem spezifischeren Zertifikat passt (z. B. ein Wildcard- oder internes CA-Zertifikat).
stores:
default:
defaultCertificate:
certFile: /certs/fullchain.pem
keyFile: /certs/privkey.pem
Die Pfade (/certs/...) sind Pfade innerhalb des Containers — wir binden sie im nächsten Schritt ein. Traefik wählt pro Anfrage das richtige Zertifikat über SNI aus, indem es den SAN des Zertifikats mit dem angeforderten Hostnamen abgleicht. Das defaultCertificate ist der Fallback, wenn nichts anderes passt.
Schritt 3: Traefik konfigurieren (statische Konfiguration + Mounts)
Hier ist eine vollständige docker-compose.yml. Die Entrypoints und der File-Provider sind statische Konfiguration (als Befehls-Flags übergeben); das Zertifikat wird aus der dynamischen Datei geladen, die Sie gerade geschrieben haben.
services:
traefik:
image: traefik:v3.3
container_name: traefik
restart: unless-stopped
command:
# ─── Entrypoints ───────────────────────────────
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
# Alle HTTP → HTTPS auf Entrypoint-Ebene weiterleiten
- "--entrypoints.web.http.redirections.entrypoint.to=websecure"
- "--entrypoints.web.http.redirections.entrypoint.scheme=https"
- "--entrypoints.web.http.redirections.entrypoint.permanent=true"
# ─── Provider ─────────────────────────────────
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
# Der File-Provider überwacht das Verzeichnis der dynamischen Konfiguration
- "--providers.file.directory=/dynamic"
- "--providers.file.watch=true"
ports:
- "80:80"
- "443:443"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "./traefik/certs:/certs:ro"
- "./traefik/dynamic:/dynamic:ro"
# ─── Beispiel-Backend-Dienst ──────────────────────
whoami:
image: traefik/whoami
container_name: whoami
labels:
- "traefik.enable=true"
# Router: den Host abgleichen, über den HTTPS-Entrypoint ausliefern
- "traefik.http.routers.whoami.rule=Host(`example.com`)"
- "traefik.http.routers.whoami.entrypoints=websecure"
# TLS auf diesem Router aktivieren — das Zertifikat stammt aus der
# dynamischen Konfiguration, NICHT aus einem Label.
- "traefik.http.routers.whoami.tls=true"
Die entscheidende Zeile ist traefik.http.routers.whoami.tls=true. Sie teilt Traefik mit: „Liefere diesen Router über TLS aus.” Traefik wählt dann das passende Zertifikat aus dem File-Provider-Store über SNI aus. Es gibt kein Label wie tls.certfile — das existiert für Router nicht.
Schritt 4: Starten und überprüfen
docker compose up -d
docker compose logs -f traefik
Achten Sie darauf, dass der File-Provider Ihr Zertifikat lädt. Sie sollten keine TLS-Fehler sehen. Überprüfen Sie dann:
Browser-Prüfung
Rufen Sie https://example.com auf. Klicken Sie auf das Schloss-Symbol:
- Ausgestellt von — Ihre CA (Let’s Encrypt für GetHTTPS oder Ihre interne CA)
- Gültig — Start- und Enddatum
- Domain — stimmt mit der URL überein
Befehlszeilen-Prüfung
# Bestätigen, dass Traefik IHR Zertifikat ausliefert und nicht sein selbstsigniertes Standardzertifikat
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -subject -issuer -dates
Wenn Sie CN=TRAEFIK DEFAULT CERT sehen, ist Traefik auf seinen integrierten Platzhalter zurückgefallen — Ihr Zertifikat wurde nicht geladen. Siehe den Abschnitt Fehlerbehebung weiter unten.
Schritt 5 (optional): TLS härten
Um Protokollversionen und Cipher zu steuern, fügen Sie Ihrer dynamischen Konfiguration einen TLS-Options-Block hinzu und referenzieren ihn vom Router aus. Fügen Sie zu certs.yml hinzu:
tls:
options:
modern:
minVersion: VersionTLS12
sniStrict: true
Dann am Router-Label:
- "traefik.http.routers.whoami.tls.options=modern@file"
Das Suffix @file teilt Traefik mit, dass dieser Options-Satz vom File-Provider stammt. Dies beschränkt Sie auf TLS 1.2 und 1.3 und lehnt Verbindungen ohne passenden SNI ab.
HSTS: Fügen Sie den
Strict-Transport-Security-Header über eine Traefik-headers-Middleware hinzu, sobald Sie sicher sind, dass HTTPS überall funktioniert. HSTS-Leitfaden →
Wie man erneuert
Traefik erneuert Zertifikate, die Sie selbst bereitstellen, nicht automatisch — das ist der Kompromiss, wenn Sie Ihr eigenes Zertifikat verwenden. Wenn Ihr Zertifikat dem Ablaufdatum nahekommt (Tag 60 von 90 bei Let’s Encrypt):
- Holen Sie sich ein neues Zertifikat von GetHTTPS (oder von Ihrem Erneuerungstool).
- Überschreiben Sie die Dateien an Ort und Stelle:
cp new-fullchain.pem ./traefik/certs/fullchain.pem cp new-privkey.pem ./traefik/certs/privkey.pem - Sonst nichts. Da
--providers.file.watch=truegesetzt ist, erkennt Traefik die Dateiänderung und lädt das Zertifikat im laufenden Betrieb neu — kein Neustart, keine Ausfallzeit. Das ist eine der schönsten Eigenschaften von Traefik bei eigenen Zertifikaten.
Vollständiger Erneuerungs-Leitfaden →
Fehlerbehebung
Traefik liefert „TRAEFIK DEFAULT CERT” statt meines Zertifikats aus
Ursache: Traefik konnte Ihr Zertifikat nicht laden und ist deshalb auf seinen selbstsignierten Platzhalter zurückgefallen. Fast immer ist es ein Pfad- oder Mount-Problem.
Lösung:
# 1. Bestätigen, dass die Dateien INNERHALB des Containers am erwarteten Pfad existieren
docker compose exec traefik ls -l /certs
# 2. Bestätigen, dass die dynamische Datei eingebunden und lesbar ist
docker compose exec traefik cat /dynamic/certs.yml
# 3. Die Logs nach dem tatsächlichen Grund durchsuchen
docker compose logs traefik | grep -i "certificate\|tls\|error"
Die Pfade certFile/keyFile in certs.yml müssen mit den Container-Pfaden (/certs/...) übereinstimmen, nicht mit Ihren Host-Pfaden.
„unable to find certificate for domain” / falsches Zertifikat wird ausgeliefert
Ursache: Kein SAN eines Zertifikats stimmt mit dem angeforderten Hostnamen überein, und es ist kein defaultCertificate gesetzt.
Lösung: Fügen Sie entweder den Hostnamen zu Ihrem Zertifikat hinzu oder setzen Sie ein defaultCertificate im stores.default-Block (Schritt 2), damit Traefik einen Fallback hat.
Router gibt 404 zurück, das Zertifikat wird gar nicht erst geprüft
Ursache: Die Router-Regel passt nicht, oder der Dienst ist nicht exponiert. TLS ist irrelevant, bis das Routing passt.
Lösung:
# Überprüfen, dass der Router existiert und aktiviert ist
docker compose exec traefik wget -qO- http://localhost:8080/api/http/routers 2>/dev/null | grep whoami
Stellen Sie sicher, dass traefik.enable=true am Backend-Container gesetzt ist und die Host()-Regel mit der Domain übereinstimmt, die Sie testen.
Änderungen an certs.yml werden nicht wirksam
Ursache: Der File-Provider überwacht nicht, oder Sie haben die statische Konfiguration bearbeitet (die einen Neustart erfordert).
Lösung: Bestätigen Sie, dass --providers.file.watch=true in der statischen Konfiguration steht. Denken Sie daran: Entrypoints/Provider sind statisch (Neustart erforderlich); Router und tls.certificates sind dynamisch (werden im laufenden Betrieb neu geladen).
„x509: certificate signed by unknown authority” von Clients
Ursache: Unvollständige Kette — Sie haben eine reine Leaf-Datei cert.pem in certFile verwendet statt fullchain.pem.
Lösung: Lassen Sie certFile auf die vollständige Kette zeigen. Wenn Sie nur separate Dateien haben, verketten Sie sie (zuerst das Leaf-Zertifikat, dann die Zwischenzertifikate):
cat cert.pem intermediate.pem > fullchain.pem
Häufig gestellte Fragen
Kann ich die Zertifikatsdatei über ein Docker-Label angeben?
Nein. Das ist das häufigste Missverständnis. Labels setzen traefik.http.routers.<name>.tls=true, um TLS zu aktivieren, aber die Zertifikatsdateien müssen in der dynamischen Konfiguration über den File-Provider deklariert werden (tls.certificates). Es gibt kein Router-Label, das auf eine .pem-Datei zeigt.
Brauche ich tls=true am Router, wenn ich ein Zertifikat habe?
Ja. Die Deklaration des Zertifikats in tls.certificates macht es verfügbar, aber jeder Router benötigt weiterhin tls=true (oder muss an einem Entrypoint mit aktiviertem TLS lauschen), um tatsächlich über HTTPS auszuliefern. Allein das Definieren eines Zertifikats schaltet einen Router nicht auf TLS um.
Kann ich automatisches ACME und eigene Zertifikate kombinieren?
Ja. Traefik kann für einige Router einen certificatesResolver und für andere File-Provider-Zertifikate verwenden. Pro Anfrage hat ein expliziter tls.certificates-Treffer über SNI Vorrang vor ACME für diesen Hostnamen.
Wohin gehören Zertifikate bei Kubernetes?
Nicht zum File-Provider — bei Kubernetes stellen Sie Zertifikate als TLS Secrets bereit und referenzieren sie von der IngressRoute/dem Ingress aus. Der File-Provider-Ansatz in dieser Anleitung ist für Docker und eigenständige (Nicht-K8s-)Setups gedacht.
Erneuert Traefik mein eigenes Zertifikat automatisch?
Nein. Die automatische Erneuerung gilt nur für Zertifikate, die Traefik selbst über ACME ausstellt. Bei Ihren eigenen Zertifikaten ersetzen Sie die Dateien — aber dank --providers.file.watch=true lädt Traefik sie ohne Ausfallzeit im laufenden Betrieb neu, wie im Abschnitt Wie man erneuert oben beschrieben.
Funktioniert das mit ECDSA-/ECC-Zertifikaten?
Ja. Traefik liefert ECDSA-Zertifikate genau wie RSA aus — dieselbe certFile/keyFile-Konfiguration. GetHTTPS stellt standardmäßig ECDSA P-256 aus für kleinere, schnellere Handshakes.