Traefik : reverse proxy Docker-native

Traefik : reverse proxy Docker-native

Traefik est le reverse proxy concu pour les environnements dynamiques : Docker, Kubernetes, Nomad. Decouverte automatique des services via labels, HTTPS Let's Encrypt automatique, dashboard temps reel.

Traefik : reverse proxy Docker-native

Traefik est le reverse proxy concu pour les environnements dynamiques : Docker, Kubernetes, Nomad. Decouverte automatique des services via labels, HTTPS Let's Encrypt automatique, dashboard temps reel.

Introduction

Traefik brille la ou Nginx peine : environnements ou les services apparaissent et disparaissent (containers, K8s). A chaque nouveau container Docker, Traefik decouvre automatiquement son routing via les labels et l'expose en HTTPS.

Caracteristiques :

  • Decouverte automatique des services (Docker, K8s, Consul, etcd, file)
  • HTTPS automatique via Let's Encrypt
  • Load balancing
  • Dashboard web temps reel
  • Middlewares riches (auth, rate limit, headers, CORS, etc.)
  • HTTP/2, HTTP/3, gRPC
  • Metrics Prometheus

Prerequis

  • VPS Debian / Ubuntu avec Docker + Docker Compose
  • Nom de domaine pointant vers le VPS
  • Ports 80, 443 ouverts
  • Acces root

Etape 1 : Structure de base

sudo mkdir -p /opt/traefik/{config,letsencrypt}
cd /opt/traefik
sudo touch letsencrypt/acme.json
sudo chmod 600 letsencrypt/acme.json

Etape 2 : Configuration statique

sudo nano /opt/traefik/config/traefik.yml
api:
  dashboard: true
  insecure: false

entryPoints:
  web:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
  websecure:
    address: ":443"
    http:
      tls:
        certResolver: letsencrypt

certificatesResolvers:
  letsencrypt:
    acme:
      email: [email protected]
      storage: /letsencrypt/acme.json
      httpChallenge:
        entryPoint: web

providers:
  docker:
    exposedByDefault: false
    network: traefik

log:
  level: INFO

accessLog: {}

Etape 3 : docker-compose.yml

sudo nano /opt/traefik/docker-compose.yml
services:
  traefik:
    image: traefik:v3.0
    container_name: traefik
    restart: unless-stopped
    networks:
      - traefik
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./config/traefik.yml:/traefik.yml:ro
      - ./letsencrypt:/letsencrypt
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.traefik.rule=Host(`traefik.votre-domaine.fr`)"
      - "traefik.http.routers.traefik.entrypoints=websecure"
      - "traefik.http.routers.traefik.service=api@internal"
      - "traefik.http.routers.traefik.middlewares=auth"
      - "traefik.http.middlewares.auth.basicauth.users=admin:$$apr1$$abc..."

networks:
  traefik:
    external: true

Creez le reseau :

sudo docker network create traefik

Generez un hash basicauth (echappez les $ en $$) :

echo $(htpasswd -nbB admin VOTRE_PASSWORD) | sed -e s/\\$/\\$\\$/g

Etape 4 : Demarrer

cd /opt/traefik
sudo docker compose up -d
sudo docker compose logs -f

Accedez au dashboard : https://traefik.votre-domaine.fr. Login : admin + le mot de passe que vous avez hashe.

Etape 5 : Exposer une app via labels

Imaginons une app web :

services:
  monapp:
    image: nginx
    networks:
      - traefik
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.monapp.rule=Host(`monapp.votre-domaine.fr`)"
      - "traefik.http.routers.monapp.entrypoints=websecure"
      - "traefik.http.routers.monapp.tls.certresolver=letsencrypt"
      - "traefik.http.services.monapp.loadbalancer.server.port=80"

networks:
  traefik:
    external: true
docker compose up -d

Visitez https://monapp.votre-domaine.fr : Traefik a obtenu un certificat et route automatiquement.

Etape 6 : Middlewares utiles

Basic auth

labels:
  - "traefik.http.middlewares.auth.basicauth.users=admin:$$apr1$$abc..."
  - "traefik.http.routers.monapp.middlewares=auth"

Rate limit

labels:
  - "traefik.http.middlewares.ratelimit.ratelimit.average=100"
  - "traefik.http.middlewares.ratelimit.ratelimit.burst=200"
  - "traefik.http.routers.monapp.middlewares=ratelimit"

Compression

labels:
  - "traefik.http.middlewares.compress.compress=true"
  - "traefik.http.routers.monapp.middlewares=compress"

Headers de securite

labels:
  - "traefik.http.middlewares.security.headers.stsSeconds=31536000"
  - "traefik.http.middlewares.security.headers.stsIncludeSubdomains=true"
  - "traefik.http.middlewares.security.headers.contentTypeNosniff=true"
  - "traefik.http.middlewares.security.headers.framedeny=true"
  - "traefik.http.routers.monapp.middlewares=security"

Chainer plusieurs middlewares

- "traefik.http.routers.monapp.middlewares=auth,ratelimit,compress,security"

Etape 7 : Whoami pour tester

Pour debugger, un container de test universel :

services:
  whoami:
    image: traefik/whoami
    networks:
      - traefik
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.whoami.rule=Host(`whoami.votre-domaine.fr`)"
      - "traefik.http.routers.whoami.entrypoints=websecure"
      - "traefik.http.routers.whoami.tls.certresolver=letsencrypt"

Affiche le hostname, l'IP, les headers recus. Tres utile pour debugger les middlewares.

Etape 8 : Wildcard avec DNS-01

Pour *.votre-domaine.fr, configurez DNS-01 challenge :

certificatesResolvers:
  letsencrypt:
    acme:
      email: [email protected]
      storage: /letsencrypt/acme.json
      dnsChallenge:
        provider: cloudflare
        resolvers:
          - "1.1.1.1:53"
          - "1.0.0.1:53"

Dans docker-compose :

environment:
  - [email protected]
  - CF_API_KEY=votre_global_api_key_cloudflare

Et sur le service :

labels:
  - "traefik.http.routers.monapp.tls.domains[0].main=votre-domaine.fr"
  - "traefik.http.routers.monapp.tls.domains[0].sans=*.votre-domaine.fr"

Etape 9 : Routing avance

Path prefix

- "traefik.http.routers.api.rule=Host(`api.votre-domaine.fr`) && PathPrefix(`/v1`)"

Multiple hosts

- "traefik.http.routers.monapp.rule=Host(`a.fr`) || Host(`b.fr`)"

Strip prefix

- "traefik.http.middlewares.strip.stripprefix.prefixes=/api"
- "traefik.http.routers.monapp.middlewares=strip"

Etape 10 : Sticky sessions

- "traefik.http.services.monapp.loadbalancer.sticky.cookie.name=session"
- "traefik.http.services.monapp.loadbalancer.sticky.cookie.secure=true"

Etape 11 : Metrics Prometheus

metrics:
  prometheus:
    addEntryPointsLabels: true
    addServicesLabels: true

Expose les metrics sur :8080/metrics. Scrapez-les avec Prometheus + Grafana.

Etape 12 : Healthcheck

labels:
  - "traefik.http.services.monapp.loadbalancer.healthcheck.path=/healthz"
  - "traefik.http.services.monapp.loadbalancer.healthcheck.interval=10s"
  - "traefik.http.services.monapp.loadbalancer.healthcheck.timeout=3s"

Traefik retire automatiquement les instances unhealthy.

Depannage

Service non discovered

Verifiez :

  • traefik.enable=true est present
  • Le container est sur le reseau traefik
  • Le router rule est valide
sudo docker logs traefik | grep monapp

Cert ne se genere pas

sudo cat /opt/traefik/letsencrypt/acme.json

Si vide : verifiez logs Traefik, DNS, ports 80/443 ouverts.

404 Page not found

Le routing n'a pas match. Verifiez :

curl -v https://monapp.votre-domaine.fr

L'host header doit correspondre exactement a la rule.

Dashboard inaccessible

Verifiez le middleware auth et que le service api@internal est bien reference.

Commandes utiles

# Voir les routers
docker exec traefik traefik healthcheck

# Logs
docker compose logs -f traefik

# Voir les certificats stockes
cat /opt/traefik/letsencrypt/acme.json | jq '.letsencrypt.Certificates[].domain.main'

# Reload (Traefik watch les changements de label automatiquement)
docker compose up -d

# Update
docker compose pull && docker compose up -d

Conclusion

Traefik est ideal pour :

  • Environnements Docker dynamiques
  • Stacks Kubernetes
  • Configurations qui changent souvent
  • Multi-tenancy

Pour de la prod simple statique, Nginx ou Caddy sont plus directs. Mais des que les containers sont en jeu, Traefik change la donne.

Pour aller plus loin :

  • Activez Traefik Pilot pour observability avancee
  • Utilisez Crowdsec bouncer pour la securite collaborative
  • Combinez avec Authelia pour SSO/MFA devant vos apps

Ressources

Join our Discord community server

For any questions, suggestions, or just to chat with the community, join us on Discord!

900+Members