
Ce guide vous accompagne dans la configuration de certificats TLS automatiques avec Traefik v3.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 »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 »| 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 »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 »| 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 »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 » ┌──────────────────────────────────────────────────────────────┐ │ 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 »-
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/whoamilabels:- "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 »| 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) »-
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.6.7environment:- 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) »-
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 »É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 »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 »Activez HSTS (HTTP Strict Transport Security) via un middleware :
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 »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 »Un lab complet est disponible pour tester toutes ces configurations :
cd ~/Projets/lab-traefik-tls-acmeStructure du lab
Section intitulée « Structure du lab »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é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 »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