Tutoriel

Traefik v3 sur VPS : reverse proxy Docker HTTPS automatique

Déploiement9 min de lecture9 étapes

Vous avez trois conteneurs Docker sur votre VPS : une app Node, un backend Python, un outil d'administration. Chacun écoute sur un port différent, vous gérez les certificats à la main, et chaque nouveau service implique de modifier nginx et de rechanger la configuration. Traefik v3 résout exactement ce problème : il lit les labels Docker de vos conteneurs, configure les routes en temps réel, renouvelle les certificats Let's Encrypt de façon autonome, et expose un dashboard de monitoring — le tout sans qu'une seule ligne de configuration nginx soit nécessaire.

Sommaire· Pourquoi Traefik v3 plutôt que nginx pour votre stack Docker1/8
  1. 01Pourquoi Traefik v3 plutôt que nginx pour votre stack Docker
  2. 02Prérequis techniques avant de commencer
  3. 03Installation complète de Traefik v3 étape par étape
  4. 04Middlewares essentiels : BasicAuth, rate-limit et headers de sécurité
  5. 05Migration depuis Traefik v2 : les changements cassants
  6. 06Traefik v3 vs nginx vs Caddy : quel reverse proxy pour Docker ?
  7. 07Dépannage : les cinq erreurs les plus fréquentes
  8. 08Prochaine étape : hardener votre stack Docker en production

Pourquoi Traefik v3 plutôt que nginx pour votre stack Docker

nginx est un excellent serveur HTTP, mais sa configuration est statique : chaque nouveau service nécessite un nouveau fichier de vhost, un rechargement du processus et souvent une modification manuelle du renouvellement ACME. Traefik a été conçu pour les environnements conteneurisés où la topologie change constamment. En version 3, il pousse cette logique encore plus loin avec le support natif de HTTP/3 (QUIC), une syntaxe de middlewares simplifiée et un runtime plus strict qui sécurise les configurations ambiguës.

  • Découverte automatique des conteneurs via les labels Docker — aucun rechargement manuel quand vous ajoutez un service.
  • HTTPS automatique avec Let's Encrypt (challenge TLS-ALPN-01 ou HTTP-01) : certificats obtenus, stockés et renouvelés sans intervention.
  • Middlewares natifs déclarables par label : BasicAuth, rate-limit, headers de sécurité, redirections — sans écrire de module nginx.
  • Dashboard temps réel intégré : visualisez toutes les routes, middlewares et état des certificats depuis un navigateur.
  • Support HTTP/3 (QUIC) en une ligne de configuration : améliore la performance sur les connexions à forte latence.
  • Routage par Host, PathPrefix, Headers ou toute combinaison — les règles s'écrivent en Go template expressif.
  • API REST interne : interrogez l'état du routeur, inspectez les backends actifs, automatisez des intégrations CI/CD.
  • Compatible Docker Swarm, Kubernetes et Nomad — vous pouvez migrer sans changer vos labels.

Prérequis techniques avant de commencer

Cette installation nécessite un VPS sous Debian 12 ou Ubuntu 22.04/24.04 (les commandes sont identiques), Docker Engine 25+ et Docker Compose v2.24+ (la commande docker compose sans tiret). Vérifiez que les ports 80 et 443 sont ouverts dans votre pare-feu — en entrée depuis Internet. Vous aurez besoin d'un nom de domaine dont vous contrôlez les DNS : pointez un enregistrement A sur l'IP de votre VPS avant de commencer, sans quoi Let's Encrypt ne pourra pas émettre le certificat. Un compte e-mail valide est requis pour les notifications d'expiration ACME.

Installation complète de Traefik v3 étape par étape

  1. Créer le réseau Docker partagé. Traefik doit être sur le même réseau que les services qu'il proxifie. Créez-le une seule fois : docker network create traefik-public. Ce réseau sera référencé dans chaque docker-compose.yml de vos services.

  2. Créer le fichier acme.json pour les certificats. Let's Encrypt écrira ses certificats dans ce fichier. Il doit appartenir à root avec les permissions 600 strictement : touch /opt/traefik/acme.json && chmod 600 /opt/traefik/acme.json. Si les permissions sont incorrectes, Traefik refusera de démarrer.

  3. Créer le docker-compose.yml Traefik. Placez ce fichier dans /opt/traefik/docker-compose.yml :

    services:
      traefik:
        image: traefik:v3.3
        container_name: traefik
        restart: unless-stopped
        ports:
          - "80:80"
          - "443:443"
          - "443:443/udp"   # HTTP/3 QUIC
        command:
          - "--api.dashboard=true"
          - "--providers.docker=true"
          - "--providers.docker.exposedbydefault=false"
          - "--entrypoints.web.address=:80"
          - "--entrypoints.web.http.redirections.entrypoint.to=websecure"
          - "--entrypoints.web.http.redirections.entrypoint.scheme=https"
          - "--entrypoints.websecure.address=:443"
          - "--entrypoints.websecure.http3=true"
          - "--certificatesresolvers.letsencrypt.acme.tlschallenge=true"
          - "--certificatesresolvers.letsencrypt.acme.email=admin@votre-domaine.com"
          - "--certificatesresolvers.letsencrypt.acme.storage=/acme.json"
          - "--log.level=INFO"
        volumes:
          - "/var/run/docker.sock:/var/run/docker.sock:ro"
          - "./acme.json:/acme.json"
        networks:
          - traefik-public
        labels:
          - "traefik.enable=true"
          - "traefik.http.routers.dashboard.rule=Host(`traefik.votre-domaine.com`)"
          - "traefik.http.routers.dashboard.entrypoints=websecure"
          - "traefik.http.routers.dashboard.tls.certresolver=letsencrypt"
          - "traefik.http.routers.dashboard.service=api@internal"
          - "traefik.http.routers.dashboard.middlewares=dashboard-auth"
          - "traefik.http.middlewares.dashboard-auth.basicauth.users=admin:$$2y$$10$$abc..."
    
    networks:
      traefik-public:
        external: true
  4. Générer le hash BasicAuth pour le dashboard. Remplacez la chaîne en dur par un vrai hash bcrypt généré avec : echo $(htpasswd -nB admin) | sed -e 's/\$/\$\$/g'. La commande htpasswd est dans le paquet apache2-utils sous Debian/Ubuntu. Les signes $ doivent être doublés ($$) dans la valeur du label Docker Compose.

  5. Démarrer Traefik. Depuis /opt/traefik/ : docker compose up -d. Vérifiez les logs : docker compose logs -f traefik. Vous devriez voir "Starting provider" providerType=Docker puis "Attaching router" routerName=dashboard. Si vous voyez une erreur sur acme.json, vérifiez les permissions.

  6. Ajouter un service derrière Traefik. Voici un exemple avec une application web Node.js. Dans son propre docker-compose.yml :

    services:
      monapp:
        image: monapp:latest
        restart: unless-stopped
        networks:
          - traefik-public
        labels:
          - "traefik.enable=true"
          - "traefik.http.routers.monapp.rule=Host(`app.votre-domaine.com`)"
          - "traefik.http.routers.monapp.entrypoints=websecure"
          - "traefik.http.routers.monapp.tls.certresolver=letsencrypt"
          - "traefik.http.services.monapp.loadbalancer.server.port=3000"
    
    networks:
      traefik-public:
        external: true

    Dès que vous faites docker compose up -d, Traefik détecte le conteneur, obtient le certificat et la route est active — sans toucher à sa propre configuration.

  7. Vérifier les certificats Let's Encrypt. Inspectez le fichier acme.json : cat /opt/traefik/acme.json | python3 -m json.tool | grep -A3 'domain'. Vous devez voir vos domaines listés avec une date d'expiration à 90 jours. Alternativement, le dashboard Traefik sur traefik.votre-domaine.com liste tous les certificats actifs sous l'onglet *Routers*.

  8. Valider la redirection HTTP→HTTPS. Testez avec curl : curl -v http://app.votre-domaine.com. Vous devez recevoir un 301 Moved Permanently vers https://. Si vous obtenez une connexion refusée sur le port 80, vérifiez que les règles de pare-feu autorisent ce port.

  9. Activer HTTP/3 côté navigateur. Ajoutez le header Alt-Svc via un middleware global dans vos labels Traefik ou dans un fichier de configuration statique traefik.yml. Le header Alt-Svc: h3=":443"; ma=86400 indique au navigateur que votre serveur supporte QUIC. Vérifiez l'activation avec curl --http3 https://app.votre-domaine.com -v.

Middlewares essentiels : BasicAuth, rate-limit et headers de sécurité

Les middlewares Traefik s'appliquent par label Docker directement sur le routeur du service concerné. Voici les trois middlewares les plus utiles en production, déclarés sur le service lui-même sans toucher à la configuration centrale de Traefik.

  • BasicAuth sur une route privée — pour protéger un outil d'administration (Adminer, Flower, etc.) : ajoutez les labels traefik.http.middlewares.adminauth.basicauth.users=admin:$$hash$$ et traefik.http.routers.monadmin.middlewares=adminauth sur le service concerné.
  • Rate-limit anti-abus — protège une API ou un formulaire de contact : traefik.http.middlewares.ratelimit.ratelimit.average=100 (100 requêtes/seconde en moyenne), traefik.http.middlewares.ratelimit.ratelimit.burst=50 (rafale de 50 tolérée). Appliquez ensuite le middleware sur le routeur : traefik.http.routers.monapi.middlewares=ratelimit.
  • Headers de sécurité HTTP — X-Frame-Options, X-Content-Type-Options, Strict-Transport-Security : le middleware headers de Traefik accepte toutes ces valeurs directement en label, sans fichier de configuration nginx séparé.
  • Redirect Regex — pour rediriger www.votre-domaine.com vers votre-domaine.com : utilisez le middleware redirectregex avec permanent=true et une regex ^https://www\.(.+) → https://${1}.
  • Compress — activez la compression gzip/brotli sur toutes les réponses textuelles avec un seul label : traefik.http.middlewares.compress.compress=true. Appliquez-le globalement en l'ajoutant comme middleware par défaut dans la configuration statique.

HTTP/3 (QUIC) en deux lignes. Dans la section command du docker-compose.yml Traefik, ajoutez --entrypoints.websecure.http3=true et exposez le port UDP 443 (443:443/udp). Le protocole QUIC établit les connexions jusqu'à 30 % plus vite sur des réseaux à pertes, et élimine le head-of-line blocking de TLS-sur-TCP. Les navigateurs modernes (Chrome 87+, Firefox 88+, Safari 16.4+) l'activent automatiquement après le premier échange via l'en-tête Alt-Svc. Aucune modification côté application n'est nécessaire.

Migration depuis Traefik v2 : les changements cassants

Traefik v3 introduit des ruptures intentionnelles avec v2 pour nettoyer les ambiguïtés accumulées. La bonne nouvelle : la migration est progressive — vous pouvez faire coexister des configurations v2 et v3 pendant la transition. Voici les points qui cassent le plus fréquemment.

  • docker.swarmMode renommé en docker.swarmmode (tout en minuscules). Si votre configuration v2 utilise l'ancienne casse, Traefik v3 l'ignore silencieusement et la découverte Swarm ne fonctionne pas.
  • Règle PathPrefix sans slash trailing : en v3, PathPrefix('/api') est équivalent à PathPrefix('/api/') — le trailing slash est normalisé. Si vous aviez des règles qui dépendaient de ce comportement pour discriminer /api de /apiv2, révisez-les.
  • tls.certificates en configuration dynamique : en v2, on pouvait définir des certificats manuels directement dans la configuration dynamique d'un fournisseur de fichiers. En v3, cette section doit être dans la configuration statique (traefik.yml) ou via un fournisseur dédié.
  • Middleware errors : le paramètre query est renommé en url. Toute configuration qui utilisait errors.query doit être mise à jour vers errors.url.
  • Suppression du support du protocole spiffe : si vous utilisiez l'authentification SPIFFE dans une infrastructure Consul, migrez vers une solution de mTLS standard avant de passer à v3.
  • Configuration Docker constraints : la syntaxe des contraintes a changé pour s'aligner sur le format standard des tags Docker. Vérifiez votre liste de contraintes si vous filtriez les services par tag.

Traefik v3 vs nginx vs Caddy : quel reverse proxy pour Docker ?

Faites défiler le tableau

CritèreTraefik v3nginxCaddy v2
ConfigurationLabels Docker, TOML ou YAML — rechargement automatique à chaudFichiers vhost statiques — rechargement manuel (`nginx -s reload`)Caddyfile déclaratif — rechargement automatique à chaud
HTTPS automatiqueIntégré nativement (ACME v2, challenge TLS-ALPN ou HTTP-01)Requiert certbot + cron + script de rechargementIntégré nativement, le plus simple à configurer (une ligne)
Routing dynamique DockerNatif : découverte en temps réel des conteneurs via le socket DockerNon natif : nécessite nginx-proxy ou modification manuelleNatif via le plugin caddy-docker-proxy (non officiel)
HTTP/3 (QUIC)Supporté nativement depuis v3 (2024), activable en une ligneSupporté depuis nginx 1.25 (2023), configuration supplémentaireSupporté nativement depuis Caddy 2.6 (2022)
Performances brutesLégèrement inférieur à nginx sur les très hauts débits (>50k req/s)Référence industrielle pour les débits élevés et la concurrenceComparable à nginx sur la plupart des charges web standard
Courbe d'apprentissageModérée — concepts de routeur/service/middleware à assimilerÉlevée pour HTTPS + Docker — documentation fragmentéeFaible — la configuration la plus concise pour des cas simples

Dépannage : les cinq erreurs les plus fréquentes

La majorité des problèmes Traefik en production viennent de trois sources : les permissions du fichier acme.json, le réseau Docker manquant, et les labels mal échappés dans Compose. Voici les erreurs avec leurs messages réels.

  • level=error msg="Unable to obtain ACME certificate" error="acme: error 403" ou unauthorized — Let's Encrypt ne peut pas vérifier votre domaine. Vérifiez que le port 80 est ouvert depuis Internet (curl http://votre-domaine.com depuis une machine externe) et que le DNS de votre domaine pointe bien sur l'IP du VPS (dig +short votre-domaine.com).
  • level=error msg="The acme.json file has bad file permissions" puis Traefik refuse de démarrer — les permissions du fichier ne sont pas 600. Corrigez : chmod 600 /opt/traefik/acme.json. Ce check est intentionnellement bloquant : un fichier lisible par d'autres utilisateurs exposerait vos clés privées.
  • Service accessible depuis le dashboard Traefik mais erreur 502 Bad Gateway — le conteneur du service n'est pas sur le réseau traefik-public. Vérifiez avec docker inspect <container> | grep -A20 Networks. Ajoutez le réseau dans le docker-compose.yml du service et recréez le conteneur.
  • Labels ignorés silencieusement, route absente du dashboard — vous avez oublié traefik.enable=true sur le service, ou --providers.docker.exposedbydefault=false est actif (recommandé) et le label est absent. Vérifiez aussi que le nom du routeur dans traefik.http.routers.<nom>.rule est unique parmi tous vos services.
  • invalid character '$' in label value — les signes $ dans les hashes BasicAuth ne sont pas doublés dans le fichier Compose. La syntaxe correcte est $$2y$$10$$... (chaque $ devient $$) quand la valeur est dans un docker-compose.yml. Si vous passez la valeur via une variable d'environnement, un seul $ suffit.

Prochaine étape : hardener votre stack Docker en production

Traefik v3 gère le routing et le TLS, mais une stack Docker production-ready demande davantage : healthchecks sur les conteneurs, politique de redémarrage, logs centralisés, rotation des secrets, sauvegardes des volumes. Consultez notre guide docker-compose-production-checklist pour une liste de contrôle complète à appliquer avant de mettre en production n'importe quel service conteneurisé sur votre VPS.

Déployez votre infrastructure dès aujourd'hui

VPS Cloud. Environnements préconfigurés disponibles.

Besoin d'aide ?

Parcourez notre centre d'aide et notre FAQ, ou contactez notre équipe — rappel, WhatsApp ou e-mail. Support en français, anglais et arabe.

Écrire sur WhatsApps'ouvre dans un nouvel onglet