Guide — Traefik v3 + Docker : HTTPS automatique (Let’s Encrypt)

Reverse proxy moderne pour vos containers : HTTP→HTTPS, certificats auto, dashboard, réseau dédié et sécurité minimale.

⏱️ 10–15 min 🧭 Traefik v3 🔐 Let’s Encrypt 🐳 Docker & Compose 📊 Dashboard sécurisé ✅ Evergreen

1) Pré-requis

  • Docker & Docker Compose installés.
  • Un domaine pointant vers votre serveur (A/AAAA) — ex. traefik.example.com et app.example.com.
  • Port 80 et 443 ouverts depuis Internet.

Traefik v3 détecte vos services via labels Docker et gère automatiquement les certificats Let’s Encrypt (HTTP challenge). Réf. docs officielles Traefik « Docker + ACME ».

2) Structure du projet

traefik/
├── docker-compose.yml
├── traefik/
│   ├── traefik.yml
│   └── dynamic/
│       └── dashboard.yml
└── data/
    └── acme.json

acme.json stocke les certificats (600). Les fichiers statiques/dynamiques séparent la config Traefik.

3) Fichier docker-compose.yml

version: "3.9"

networks:
  proxy:
    name: proxy
    external: false

services:
  traefik:
    image: traefik:latest  # v3.x
    container_name: traefik
    restart: unless-stopped
    command:
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.le.acme.email=${LE_EMAIL}"
      - "--certificatesresolvers.le.acme.storage=/letsencrypt/acme.json"
      - "--certificatesresolvers.le.acme.httpchallenge=true"
      - "--certificatesresolvers.le.acme.httpchallenge.entrypoint=web"
      # Dashboard (via fichier dynamique)
      - "--api.dashboard=true"
      - "--providers.file.directory=/etc/traefik/dynamic"
      - "--providers.file.watch=true"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./data/acme.json:/letsencrypt/acme.json
      - ./traefik/traefik.yml:/etc/traefik/traefik.yml:ro
      - ./traefik/dynamic:/etc/traefik/dynamic:ro
    networks:
      - proxy
    labels:
      - "traefik.enable=true"
      # Rediriger HTTP->HTTPS globalement (middleware + router)
      - "traefik.http.middlewares.redirect-https.redirectscheme.scheme=https"
      - "traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)"
      - "traefik.http.routers.http-catchall.entrypoints=web"
      - "traefik.http.routers.http-catchall.middlewares=redirect-https"
Sécurité : le socket Docker est monté en ro. Pour durcir, utilisez un proxy comme traefik/traefik via docker-proxy ou des projets type socket-proxy.

4) Fichiers & secrets

Variables

# .env
LE_EMAIL=admin@example.com
DASH_USER=admin
DASH_PASS_HASH=$2y$05$RemplacezParUnHashBcrypt

Config statique

# traefik/traefik.yml
log:
  level: INFO
api:
  dashboard: true

serversTransport:
  insecureSkipVerify: false

Dashboard sécurisé (Basic Auth)

# traefik/dynamic/dashboard.yml
http:
  routers:
    traefik-dashboard:
      rule: "Host(`traefik.example.com`)"
      entryPoints: ["websecure"]
      service: "api@internal"
      tls:
        certResolver: "le"
      middlewares: ["auth"]
  middlewares:
    auth:
      basicAuth:
        users:
          - "${DASH_USER}:${DASH_PASS_HASH}"

ACME store

# data/acme.json
# (fichier vide mais présent) — chmod 600

Générez le hash bcrypt avec htpasswd -nbB admin MonMotDePasse (paquet apache2-utils), ou via un générateur équivalent.

5) Lancement & vérifications

Préparer

cd traefik
touch data/acme.json && chmod 600 data/acme.json

Démarrer

docker compose --env-file .env up -d

Sanity checks

docker ps
# → "traefik" doit être "Up"
docker logs -f traefik
# → cherchez "Server configuration reloaded" et ACME "lego" sans erreurs

Ouvrez https://traefik.example.com → prompt Basic Auth → dashboard.

6) Exposer un service derrière Traefik

Ajoutez vos services au même réseau proxy et posez des labels. Exemple avec traefik/whoami :

# Ajoutez au docker-compose.yml
  whoami:
    image: traefik/whoami
    restart: unless-stopped
    networks:
      - proxy
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.whoami.rule=Host(`app.example.com`)"
      - "traefik.http.routers.whoami.entrypoints=websecure"
      - "traefik.http.routers.whoami.tls.certresolver=le"

Déployez :

docker compose up -d whoami
# puis visitez https://app.example.com
Wildcard / DNS challenge : pour un certificat *.example.com, passez au DNS challenge avec vos API DNS (Cloudflare, etc.).

7) Bonnes pratiques

  • Réseau dédié : gardez un réseau proxy unique pour les services exposés.
  • Redirection HTTP→HTTPS activée globalement (middleware).
  • Secrets : stockez DASH_PASS_HASH dans un coffre (Vault, SOPS, Docker secrets).
  • ACME : sauvegardez data/acme.json (chmod 600). Ne le perdez pas → rate limits LE.
  • MàJ : docker compose pull puis up -d. Relisez les notes de version v3.
  • Durcissement : évitez l’accès direct au socket Docker (socket-proxy), limitez les capacités, user non-root.

8) Dépannage rapide

ProblèmeCause probableSolution
Certificats non émis Ports 80/443 fermés ou DNS incorrect Ouvrir 80/443 ; vérifier A/AAAA ; regarder docker logs traefik (ACME).
Dashboard 404 Router/middlewares manquants Vérifier dashboard.yml (rule/entrypoints/tls) et le domaine traefik.example.com.
Service inaccessible Labels ou réseau Confirmer traefik.enable=true, la rule, l’entrypoint et le réseau proxy.
Rate limit Let’s Encrypt Trop d’émissions Tester en « staging » ACME, réutiliser acme.json, éviter les recréations.