
Ce guide vous accompagne dans la configuration de certificats TLS automatiques avec Traefik v3.7.6. Vous apprendrez à utiliser Let's Encrypt via le protocole ACME pour obtenir des certificats gratuits, que ce soit par HTTP Challenge (le plus simple) ou DNS Challenge (pour les wildcards et réseaux privés). À la fin, vos services seront accessibles en HTTPS avec des certificats renouvelés automatiquement.
Temps estimé : 20-25 minutes selon votre configuration.
Prérequis
Section intitulée « Prérequis »Vérifiez ces points avant de commencer : un manque à ce stade se manifeste bien plus tard, sous la forme d'une erreur qui ne le désigne pas.
Domaine pointant vers Traefik
Section intitulée « Domaine pointant vers Traefik »Vous devez avoir un nom de domaine dont les enregistrements DNS pointent vers l'IP de votre serveur Traefik :
# Vérifier que votre domaine pointe vers votre serveurdig +short mon-domaine.com A# Doit retourner l'IP de votre serveurPorts réseau
Section intitulée « Ports réseau »Le port à ouvrir dépend du challenge retenu, et cette contrainte est souvent ce qui décide du choix. Notez la particularité du DNS-01 : il n'exige aucun port entrant, seulement un accès sortant vers l'API de votre hébergeur DNS. Un serveur derrière un pare-feu d'entreprise ne peut donc obtenir de certificat que par cette voie.
| Challenge | Port requis | Direction |
|---|---|---|
| HTTP-01 | 80 | Entrant depuis Internet |
| TLS-ALPN-01 | 443 | Entrant depuis Internet |
| DNS-01 | Aucun | Sortant vers API DNS |
Vérifiez l'accessibilité depuis l'extérieur :
# Depuis un autre serveur ou https://www.whatsmyip.org/port-scanner/nc -zv votre-ip-publique 80nc -zv votre-ip-publique 443Traefik installé
Section intitulée « Traefik installé »Ce guide suppose que Traefik est déjà installé. Si ce n'est pas le cas, consultez d'abord Installer Traefik v3.
Compte DNS provider (pour DNS Challenge)
Section intitulée « Compte DNS provider (pour DNS Challenge) »Si vous utilisez le DNS Challenge, vous aurez besoin d'un accès API à votre provider DNS (Cloudflare, OVH, Route53, etc.).
Comment fonctionne ACME
Section intitulée « Comment fonctionne ACME »Comprendre le protocole évite des heures de dépannage à l'aveugle : la plupart des erreurs de certificat sont en réalité des échecs de validation de domaine, pas des problèmes de configuration TLS. Cette section décrit l'échange entre Traefik et l'autorité de certification, puis les trois manières de prouver que le domaine vous appartient.
Le protocole ACME
Section intitulée « Le protocole ACME »ACME (Automatic Certificate Management Environment) est le protocole utilisé par Let's Encrypt pour automatiser la délivrance de certificats. Voici comment ça fonctionne :
- Votre serveur demande un certificat pour un domaine (ex:
api.exemple.com) - Let's Encrypt vous lance un défi : "Prouvez que vous contrôlez ce domaine"
- Vous relevez le défi (via HTTP, DNS ou TLS selon le type choisi)
- Let's Encrypt vérifie et délivre le certificat
Les certificats Let's Encrypt sont gratuits et valides 90 jours. Traefik gère automatiquement le renouvellement (généralement 30 jours avant expiration).
Les trois types de challenges
Section intitulée « Les trois types de challenges »Les trois challenges prouvent la même chose par des canaux différents. Une seule différence est structurelle plutôt que pratique : seul DNS-01 permet d'obtenir un certificat wildcard, car Let's Encrypt exige alors une preuve au niveau du domaine entier, ce qu'une requête HTTP sur un hôte donné ne peut pas fournir.
| Challenge | Comment ça marche | Quand l'utiliser |
|---|---|---|
| HTTP-01 | Let's Encrypt fait une requête HTTP sur /.well-known/acme-challenge/ | Port 80 accessible, cas le plus courant |
| DNS-01 | Vous créez un enregistrement TXT _acme-challenge.domaine | Wildcard, port 80 fermé, réseau privé |
| TLS-ALPN-01 | Vérification via TLS sur le port 443 | Port 80 fermé mais 443 ouvert |
Configuration de base Let's Encrypt
Section intitulée « Configuration de base Let's Encrypt »Trois éléments sont à mettre en place, et ils vivent dans deux endroits différents de Traefik. Le certificate resolver et son fichier de stockage appartiennent à la configuration statique, lue une seule fois au démarrage : toute modification impose un redémarrage. L'activation sur un router, elle, relève de la configuration dynamique, rechargée à chaud. Confondre les deux est la cause d'une bonne partie des configurations qui « ne prennent pas ».
Certificate Resolver
Section intitulée « Certificate Resolver »Un Certificate Resolver est la configuration qui indique à Traefik comment obtenir des certificats. Vous le définissez dans la configuration statique :
# traefik.yaml - Configuration statiquecertificatesResolvers: letsencrypt: acme: email: "admin@votre-domaine.com" # Email pour les notifications storage: /etc/traefik/acme.json # Où stocker les certificats caServer: "https://acme-v02.api.letsencrypt.org/directory" httpChallenge: entryPoint: web # Entrypoint pour le challenge HTTP[certificatesResolvers.letsencrypt.acme] email = "admin@votre-domaine.com" storage = "/etc/traefik/acme.json" caServer = "https://acme-v02.api.letsencrypt.org/directory" [certificatesResolvers.letsencrypt.acme.httpChallenge] entryPoint = "web"--certificatesresolvers.letsencrypt.acme.email=admin@votre-domaine.com \--certificatesresolvers.letsencrypt.acme.storage=/etc/traefik/acme.json \--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=webStockage des certificats (acme.json)
Section intitulée « Stockage des certificats (acme.json) »Les certificats obtenus sont stockés dans un fichier JSON. Ce fichier doit avoir des permissions strictes car il contient vos clés privées :
# Créer le fichier avec les bonnes permissionstouch /etc/traefik/acme.jsonchmod 600 /etc/traefik/acme.jsonAvec Docker, créez le fichier avant de lancer le conteneur :
mkdir -p ~/traefik/certstouch ~/traefik/certs/acme.jsonchmod 600 ~/traefik/certs/acme.jsonActiver TLS sur un router
Section intitulée « Activer TLS sur un router »Une fois le resolver configuré, activez-le sur vos routers :
services: mon-app: image: mon-image labels: - "traefik.enable=true" - "traefik.http.routers.mon-app.rule=Host(`app.exemple.com`)" - "traefik.http.routers.mon-app.entrypoints=websecure" - "traefik.http.routers.mon-app.tls=true" - "traefik.http.routers.mon-app.tls.certresolver=letsencrypt"http: routers: mon-app: rule: "Host(`app.exemple.com`)" entryPoints: - websecure service: mon-app tls: certResolver: letsencryptHTTP Challenge
Section intitulée « HTTP Challenge »C'est la méthode la plus simple. Let's Encrypt vérifie que vous contrôlez le domaine en faisant une requête HTTP sur le port 80.
Fonctionnement
Section intitulée « Fonctionnement »Cet enchaînement se déroule en quelques secondes et sans intervention de votre part. Le point de rupture le plus fréquent est l'étape 3 : la requête vient des serveurs de Let's Encrypt, donc depuis Internet, et doit atteindre le port 80 de votre machine. Un test local réussi ne prouve rien.
┌──────────────────────────────────────────────────────────────┐ │ HTTP-01 Challenge │ └──────────────────────────────────────────────────────────────┘
1. Traefik demande un certificat pour app.exemple.com
2. Let's Encrypt génère un token unique
3. Let's Encrypt fait une requête : GET http://app.exemple.com/.well-known/acme-challenge/{token}
4. Traefik répond avec la preuve de contrôle
5. Let's Encrypt délivre le certificatConfiguration complète
Section intitulée « Configuration complète »Les cinq étapes ci-dessous se suivent dans l'ordre. Gardez le port 80 ouvert
même si vous redirigez tout vers HTTPS à l'étape 4 : la redirection renvoie les
visiteurs, mais Traefik continue de répondre lui-même aux requêtes
/.well-known/acme-challenge/ sur cet entrypoint.
-
Configurer les entrypoints
Vous avez besoin de deux entrypoints : un pour HTTP (port 80) et un pour HTTPS (port 443) :
traefik.yaml entryPoints:web:address: ":80"websecure:address: ":443" -
Configurer le certificate resolver
traefik.yaml certificatesResolvers:letsencrypt:acme:email: "admin@exemple.com"storage: /etc/traefik/acme.jsonhttpChallenge:entryPoint: web -
Activer TLS sur vos services
# docker-compose.yml - Service avec HTTPSservices:whoami:image: traefik/whoami:v1.11.0@sha256:200689790a0a0ea48ca45992e0450bc26ccab5307375b41c84dfc4f2475937ablabels:- "traefik.enable=true"- "traefik.http.routers.whoami.rule=Host(`whoami.exemple.com`)"- "traefik.http.routers.whoami.entrypoints=websecure"- "traefik.http.routers.whoami.tls.certresolver=letsencrypt" -
Redirection HTTP vers HTTPS (optionnel mais recommandé)
Ajoutez une redirection automatique dans les entrypoints :
traefik.yaml entryPoints:web:address: ":80"http:redirections:entryPoint:to: websecurescheme: httpspermanent: true -
Vérifier le certificat
Fenêtre de terminal # Attendre quelques secondes que le certificat soit générécurl -v https://whoami.exemple.com 2>&1 | grep -A5 "Server certificate"# Ou avec opensslecho | openssl s_client -connect whoami.exemple.com:443 -servername whoami.exemple.com 2>/dev/null | openssl x509 -noout -issuer -subject -datesRésultat attendu :
issuer=C = US, O = Let's Encrypt, CN = R3subject=CN = whoami.exemple.comnotBefore=Feb 17 12:00:00 2026 GMTnotAfter=May 18 12:00:00 2026 GMT
DNS Challenge
Section intitulée « DNS Challenge »Le DNS Challenge est nécessaire pour les certificats wildcard (ex: *.exemple.com) ou quand le port 80 n'est pas accessible depuis Internet.
Pourquoi utiliser DNS Challenge
Section intitulée « Pourquoi utiliser DNS Challenge »Le DNS Challenge coûte plus cher en configuration : il faut un token d'API chez votre hébergeur DNS, donc un secret à protéger et à faire tourner. En contrepartie, il fonctionne dans des situations où le HTTP Challenge est impossible, notamment sur un service qui n'est jamais exposé à Internet. Le tableau ci-dessous résume les cas où le choix n'en est pas un.
| Situation | HTTP Challenge | DNS Challenge |
|---|---|---|
| Port 80 ouvert | ✅ | ✅ |
| Port 80 fermé (entreprise) | ❌ | ✅ |
| Certificat wildcard | ❌ | ✅ |
| Réseau privé (homelab) | ❌ | ✅ |
| Multi-domaines sur un certificat | ✅ | ✅ |
Providers DNS supportés
Section intitulée « Providers DNS supportés »Traefik supporte plus de 100 providers DNS. Voici les plus courants :
| Provider | Provider name | Variables d'environnement |
|---|---|---|
| Cloudflare | cloudflare | CF_API_EMAIL, CF_DNS_API_TOKEN |
| OVH | ovh | OVH_ENDPOINT, OVH_APPLICATION_KEY, OVH_APPLICATION_SECRET, OVH_CONSUMER_KEY |
| AWS Route53 | route53 | AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION |
| Google Cloud DNS | gcloud | GCE_PROJECT, credentials file |
| Azure DNS | azure | AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_TENANT_ID, AZURE_SUBSCRIPTION_ID, AZURE_RESOURCE_GROUP |
| Hetzner | hetzner | HETZNER_API_KEY |
| DigitalOcean | digitalocean | DO_AUTH_TOKEN |
La liste complète est disponible sur lego DNS providers.
Configuration DNS Challenge (Cloudflare)
Section intitulée « Configuration DNS Challenge (Cloudflare) »Le token créé ici donne le droit de modifier vos enregistrements DNS : limitez-le à la zone concernée, comme indiqué à la première étape, et traitez-le comme un mot de passe d'administration.
-
Créer un token API Cloudflare
Dans Cloudflare Dashboard → My Profile → API Tokens → Create Token :
- Template : Edit zone DNS
- Zone Resources : Include → Specific zone → votre domaine
- Copiez le token généré
-
Configurer le resolver avec DNS Challenge
traefik.yaml certificatesResolvers:letsencrypt-dns:acme:email: "admin@exemple.com"storage: /etc/traefik/acme.jsondnsChallenge:provider: cloudflarepropagation:delayBeforeChecks: 10sresolvers:- "1.1.1.1:53"- "8.8.8.8:53" -
Passer les variables d'environnement
docker-compose.yml services:traefik:image: traefik:v3.7.6@sha256:21a3d83696379bac6434bb32e1dde0aff0e84ef2abd053ed3db87d3f45e749b2environment:- CF_API_EMAIL=votre-email@exemple.com- CF_DNS_API_TOKEN=votre-token-cloudflare# ... -
Configurer un certificat wildcard
services:traefik:labels:- "traefik.http.routers.wildcard.tls.certresolver=letsencrypt-dns"- "traefik.http.routers.wildcard.tls.domains[0].main=exemple.com"- "traefik.http.routers.wildcard.tls.domains[0].sans=*.exemple.com"
Configuration DNS Challenge (OVH)
Section intitulée « Configuration DNS Challenge (OVH) »OVH demande quatre valeurs au lieu d'un token unique, et sa propagation DNS
est plus lente que celle de Cloudflare : le delayBeforeChecks passe ici à 30
secondes. Les trois droits accordés au token correspondent exactement au cycle
de vie de l'enregistrement TXT de validation : le lire, le créer, le supprimer.
-
Créer les clés API OVH
Rendez-vous sur https://eu.api.ovh.com/createToken/ et créez un token avec les droits :
GET /domain/zone/*POST /domain/zone/*DELETE /domain/zone/*
-
Configurer Traefik
traefik.yaml certificatesResolvers:letsencrypt-dns:acme:email: "admin@exemple.com"storage: /etc/traefik/acme.jsondnsChallenge:provider: ovhpropagation:delayBeforeChecks: 30s # OVH peut être lent -
Variables d'environnement
docker-compose.yml environment:- OVH_ENDPOINT=ovh-eu- OVH_APPLICATION_KEY=xxx- OVH_APPLICATION_SECRET=xxx- OVH_CONSUMER_KEY=xxx
Environnement staging Let's Encrypt
Section intitulée « Environnement staging Let's Encrypt »Let's Encrypt met à disposition un environnement de test, dit staging, qui parle le même protocole mais délivre des certificats non reconnus par les navigateurs. Son intérêt est ailleurs : ses quotas sont bien plus larges que ceux de la production. Tant que votre configuration n'est pas validée, c'est le seul endroit où il faut se tromper.
Éviter les rate limits
Section intitulée « Éviter les rate limits »Let's Encrypt impose des limites strictes en production :
| Limite | Valeur |
|---|---|
| Certificats par domaine | 50 / semaine |
| Échecs de validation | 5 / heure / compte |
| Nouveaux enregistrements | 10 / 3 heures / IP |
Configuration staging
Section intitulée « Configuration staging »Ajoutez le serveur staging dans votre configuration :
certificatesResolvers: letsencrypt-staging: acme: email: "admin@exemple.com" storage: /etc/traefik/acme-staging.json # Fichier séparé ! caServer: "https://acme-staging-v02.api.letsencrypt.org/directory" httpChallenge: entryPoint: webUtilisez ce resolver pour vos tests :
- "traefik.http.routers.test.tls.certresolver=letsencrypt-staging"Passer en production
Section intitulée « Passer en production »Une fois que le staging fonctionne :
- Changez le resolver vers
letsencrypt(production) - Supprimez le fichier
acme-staging.json - Redémarrez Traefik
rm /etc/traefik/acme-staging.jsondocker compose restart traefikOptions TLS avancées
Section intitulée « Options TLS avancées »Obtenir un certificat ne dit rien de la qualité de la connexion négociée ensuite. Ces réglages portent sur les versions de TLS acceptées, les algorithmes de chiffrement autorisés et le comportement face à un client qui n'annonce pas le nom du site demandé. Ils vivent tous dans la configuration dynamique, donc rechargeable sans redémarrage.
TLS Options
Section intitulée « TLS Options »Définissez des profils TLS réutilisables pour contrôler les versions et cipher suites :
tls: options: # Profil moderne (TLS 1.3 uniquement) modern: minVersion: VersionTLS13 sniStrict: true
# Profil intermédiaire (compatibilité TLS 1.2) intermediate: minVersion: VersionTLS12 cipherSuites: - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305Appliquez un profil à un router :
# Docker labels- "traefik.http.routers.secure-app.tls.options=modern@file"SNI strict
Section intitulée « SNI strict »Le SNI (Server Name Indication) permet d'héberger plusieurs certificats sur une même IP. Avec sniStrict: true, Traefik rejette les connexions qui ne fournissent pas de SNI valide :
tls: options: strict: minVersion: VersionTLS12 sniStrict: true # Rejette les connexions sans SNIHeaders de sécurité HSTS
Section intitulée « Headers de sécurité HSTS »HSTS (HTTP Strict Transport Security) est un en-tête qui ordonne au
navigateur de ne plus jamais contacter votre domaine en clair pendant la durée
indiquée. Deux options méritent réflexion avant activation.
stsIncludeSubdomains étend la règle à tous les sous-domaines, y compris ceux
qui n'ont pas encore de certificat. stsPreload sert à une inscription dans la
liste embarquée des navigateurs, dont la sortie prend des mois : ne l'activez
que si HTTPS fonctionne partout, durablement.
http: middlewares: hsts: headers: stsSeconds: 31536000 # 1 an stsIncludeSubdomains: true stsPreload: true forceSTSHeader: trueAppliquez-le à vos routers :
- "traefik.http.routers.app.middlewares=hsts@file"Renouvellement des certificats
Section intitulée « Renouvellement des certificats »Un certificat Let's Encrypt vit 90 jours, ce qui rend le renouvellement automatique indispensable. Traefik s'en charge seul, mais deux points restent à votre charge : surveiller que le renouvellement a bien lieu, et savoir le forcer quand un certificat doit être remplacé avant terme, par exemple après l'ajout d'un sous-domaine.
Automatique par Traefik
Section intitulée « Automatique par Traefik »Traefik renouvelle automatiquement les certificats 30 jours avant leur expiration. Vous n'avez rien à faire.
Le processus se déclenche au démarrage de Traefik et vérifie tous les certificats stockés dans acme.json.
Monitoring des expirations
Section intitulée « Monitoring des expirations »Surveillez les certificats avec les métriques Prometheus :
metrics: prometheus: entryPoint: metrics addServicesLabels: trueMétrique disponible : traefik_tls_certs_not_after_timestamp
Exemple d'alerte Alertmanager :
- alert: CertificateExpiringSoon expr: (traefik_tls_certs_not_after_timestamp - time()) / 86400 < 14 for: 1h labels: severity: warning annotations: summary: "Certificat expire dans moins de 14 jours"Forcer le renouvellement
Section intitulée « Forcer le renouvellement »Si vous devez forcer un renouvellement :
# Sauvegarder puis supprimer le certificatcp /etc/traefik/acme.json /etc/traefik/acme.json.bak
# Supprimer uniquement le certificat concerné (avec jq)jq 'del(.letsencrypt.Certificates[] | select(.domain.main == "exemple.com"))' \ /etc/traefik/acme.json > /tmp/acme.json && mv /tmp/acme.json /etc/traefik/acme.json
# Redémarrer Traefikdocker compose restart traefikLab : configuration complète
Section intitulée « Lab : configuration complète »Toutes les configurations de ce guide sont regroupées dans un lab local. Il permet de vérifier le démarrage de Traefik, les permissions du fichier de stockage et le chargement de la configuration dynamique sans consommer de quota chez Let's Encrypt, puisqu'aucun certificat réel n'est demandé.
cd ~/Projets/lab-traefik-tls-acmeStructure du lab
Section intitulée « Structure du lab »Cette arborescence reprend la séparation vue plus haut : traefik.yaml porte la
configuration statique, tout ce qui se trouve sous dynamic/ est rechargé à
chaud, et certs/ isole le fichier sensible.
lab-traefik-tls-acme/├── docker-compose.yml # Stack Docker├── config/│ ├── traefik.yaml # Configuration statique│ └── dynamic/│ ├── tls.yaml # Options TLS│ └── middlewares.yaml # Middlewares HTTPS└── certs/ └── acme.json # Stockage certificats (chmod 600)Démarrage rapide
Section intitulée « Démarrage rapide »Créez acme.json avant le premier docker compose up : lancé sur un chemin
inexistant, Docker crée un répertoire à la place du fichier et Traefik refuse de
démarrer. Le -k du dernier curl accepte le certificat auto-signé servi en
local, et l'en-tête Host simule le nom de domaine attendu par le router.
# Créer le fichier de certificatstouch certs/acme.json && chmod 600 certs/acme.json
# Démarrer avec certificats auto-signés (pour tests locaux)docker compose up -d
# Vérifier les logsdocker compose logs -f traefik
# Testercurl -k https://localhost:8443 -H "Host: whoami.localhost"Dépannage
Section intitulée « Dépannage »Pour inspecter finement un certificat servi (chaîne, SNI, expiration, version TLS négociée), le guide diagnostic TLS avec openssl détaille la lecture d'openssl s_client et des codes de vérification.
Certificat non généré
Section intitulée « Certificat non généré »Symptôme : pas de certificat, erreur 526 ou certificat auto-signé affiché.
Vérifications :
# 1. Vérifier les logs Traefikdocker compose logs traefik | grep -i acme
# 2. Vérifier que le port 80 est accessiblecurl http://votre-domaine.com
# 3. Vérifier le DNSdig +short votre-domaine.com A
# 4. Vérifier le fichier acme.jsoncat /etc/traefik/acme.json | jq '.letsencrypt'Solutions courantes :
| Erreur | Cause | Solution |
|---|---|---|
| "acme: error validating" | Port 80 bloqué | Ouvrir le firewall ou utiliser DNS Challenge |
| "too many certificates" | Rate limit atteint | Attendre 1 semaine ou utiliser staging |
| "DNS problem" | DNS mal configuré | Vérifier les enregistrements A/AAAA |
Erreur "too many certificates"
Section intitulée « Erreur "too many certificates" »Vous avez atteint la limite Let's Encrypt. Options :
- Attendre : la limite se réinitialise après 7 jours
- Utiliser staging : pas de limite pour les tests
- Utiliser un wildcard : un seul certificat pour tous les sous-domaines
DNS propagation timeout
Section intitulée « DNS propagation timeout »Avec le DNS Challenge, Let's Encrypt peut ne pas voir l'enregistrement TXT à temps.
# Augmenter le délaicertificatesResolvers: letsencrypt-dns: acme: dnsChallenge: provider: ovh propagation: delayBeforeChecks: 60s # Augmenter à 60s voire plusVous pouvez aussi spécifier des resolvers DNS rapides :
resolvers: - "1.1.1.1:53" # Cloudflare - "8.8.8.8:53" # GoogleCertificat staging en production
Section intitulée « Certificat staging en production »Si votre certificat est signé par "Fake LE" en production :
- Vérifiez que vous utilisez le bon resolver (pas
-staging) - Supprimez
acme.jsonet redémarrez pour forcer un nouveau certificat - Vérifiez les logs pour les erreurs ACME
À retenir
Section intitulée « À retenir »- Let's Encrypt fournit des certificats TLS gratuits et automatiques via le protocole ACME
- HTTP Challenge est le plus simple (port 80 requis), DNS Challenge permet les wildcards
- Toujours tester avec staging avant de passer en production pour éviter les rate limits
- Le fichier
acme.jsondoit avoir les permissions 600 (lecture/écriture propriétaire uniquement) - Traefik renouvelle automatiquement les certificats 30 jours avant expiration
- Utilisez les TLS Options pour définir des profils de sécurité réutilisables