Migration Traefik v2 vers v3 : ce qui casse
Traefik v3 refuse `swarmMode` et `pilot` dans la configuration statique. Corrigez l’erreur « incompatible deprecated install configuration option », puis migrez les règles.
Ce qui change entre Traefik v2 et v3
La migration de Traefik v2 vers v3 consiste principalement à renommer des éléments. Le renommage le plus connu concerne le middleware ipWhiteList, devenu ipAllowList. En outre, v3 durcit la syntaxe des règles des routeurs : PathPrefix perd ses fonctionnalités liées aux expressions régulières, plusieurs matchers sont renommés ou supprimés, et quelques providers et options sont entièrement abandonnés. Le reste continue de fonctionner : les entrypoints, la configuration des certificats ACME, le workflow basé sur les labels Docker et votre acme.json sont conservés. v3 fournit aussi un mode de compatibilité qui permet de continuer à utiliser la syntaxe des règles de v2. Vous pouvez donc mettre à niveau le binaire d’abord, puis réécrire les règles service par service, au lieu de tout modifier au cours d’une seule intervention risquée.
Ce guide part de la configuration Docker Compose basée sur les labels présentée dans le guide du reverse proxy Traefik. Cette page utilise nativement v3 ; celle-ci concerne le serveur qui exécute encore un tag traefik:v2.
Les renommages et les suppressions
ipWhiteListdevientipAllowList, pour les middlewares HTTP et TCP. Les options qu’il contient ne changent pas.sourcerangeconserve donc exactement le même fonctionnement. Les releases v3 actuelles, y compris v3.7, acceptent encore l’ancien nom comme alias obsolète et continuent d’appliquer la liste. Elles journalisent un avertissement d’obsolescence. Ce renommage ne provoque donc pas d’interruption lors du basculement. Renommez-le malgré tout : l’ancien nom est obsolète, et v2.11 comprend déjàipAllowList. Le renommage peut donc être déployé avant la mise à niveau.providers.docker.swarmMode=truea été supprimé. Swarm dispose de son propre provider, configuré avecproviders.swarm.endpoint.- La section
pilota été entièrement supprimée. experimental.http3a été supprimé. HTTP/3 est directement activé sur l’entrypoint.tls.caOptionala été supprimé des providers et du middleware forwardAuth. Si ce middleware protège un SSO Authentik auto-hébergé, supprimer la lignecaOptionalsuffit pour effectuer la migration. L’adresse forwardAuth, les en-têtes de confiance et l’outpost correspondant fonctionnent tous de la même manière avec v3.- Le provider de métriques InfluxDB v1, le provider Rancher et le provider Marathon ont été supprimés.
- Le tracing utilise désormais OpenTelemetry. Les backends de tracing dédiés, notamment les intégrations Jaeger et Zipkin, ont été supprimés. v3 exporte à la place via OTLP (le protocole OpenTelemetry).
- Les options
ssl*obsolètes du middleware headers (sslRedirect,sslHostet les autres) ont été supprimées. Les redirections des entrypoints et le middleware redirectScheme les remplacent.
Ces suppressions sont plus importantes qu’il n’y paraît, car Traefik refuse de démarrer lorsque sa configuration statique contient une option supprimée ou inconnue. Une ligne pilot, swarmMode, experimental.http3 ou provider tls.caOptional restante arrête le conteneur au démarrage : Traefik journalise d’abord une ligne qui nomme l’élément restant, par exemple, l’option tls.CAOptional du provider Docker a été supprimée dans v3, puis échoue avec incompatible deprecated install configuration option found. Les releases jusqu’à v3.4 formulent ce dernier message comme incompatible deprecated static option found. Une option que Traefik ne connaît tout simplement pas, par exemple à cause d’une faute de frappe, provoque l’arrêt avec field not found, et le nœud s’arrête également. Nettoyez la configuration statique avant de modifier le tag de l’image.
Un nom de middleware que Traefik ne connaît réellement pas, à cause d’une faute de frappe ou parce que le nom a été supprimé sans alias, échoue différemment : le router qui le référence est chargé avec une erreur au lieu d’une route, le dashboard le signale et l’API renvoie middleware "offce@docker" does not exist. Les requêtes vers ce hostname reçoivent une réponse 404, car le router n’a jamais démarré. Notez que ipwhitelist n’entre PAS dans cette catégorie avec les versions actuelles de v3 : il reste disponible comme alias obsolète. Un label qui n’a pas été renommé continue donc de fonctionner sans incident.
La syntaxe des règles change
Les règles permettent d’effectuer les réécritures proprement dites. Voici les changements dans la v3 :
- Les guillemets ne sont pas concernés. Les deux versions attendent les valeurs des règles entre accents graves ou entre guillemets doubles échappés et refusent les guillemets simples.
Host(app.example.com)etHost("app.example.com")avec des guillemets doubles échappés restent donc valides tels quels. PathPrefixne prend plus en charge les expressions régulières ni les paramètres fictifs de type{id}. Une règle v2 telle quePathPrefix(/api/{version:v[0-9]+})doit devenir un matcherPathRegexpécrit avec la syntaxe des expressions régulières Go.- Les matchers n’acceptent désormais qu’une seule valeur. La v2 autorisait
Host(app.example.com,www.example.com); la v3 attendHost(app.example.com) || Host(www.example.com). Les exceptions sontHeader,HeaderRegexp,QueryetQueryRegexp, qui acceptent toujours un nom et une valeur. HeadersetHeadersRegexpsont renommés enHeaderetHeaderRegexp.HostHeaderest supprimé. UtilisezHost, qui effectue la même correspondance dans la v3.- Deux matchers sont nouveaux :
PathRegexpetQueryRegexp.ClientIP, qui permet de faire correspondre l’adresse du client dans une règle, existait déjà dans la v2.11 et reste inchangé.
La bonne nouvelle : une règle Host(app.example.com) simple, écrite avec des accents graves, est déjà valide avec la syntaxe v3. La plupart des petites configurations Compose utilisent exactement cette forme. La plupart des labels peuvent donc être migrés sans modifier les règles.
Auditez vos labels avant de commencer
Vous pouvez mesurer l’ampleur de la migration avec une seule recherche, car chaque modification incompatible d’un label laisse un motif que grep peut trouver :
grep -rnE 'ipwhitelist|HostHeader|Headers\(|PathPrefix\(`[^`]*\{|Host\(`[^`]*`,' docker-compose*.ymlChaque résultat correspond à une ligne à modifier. ipwhitelist devient ipallowlist. HostHeader devient Host. Headers devient Header. Un placeholder {...} à l’intérieur de PathPrefix devient un matcher PathRegexp. Une virgule dans Host() devient deux matchers Host() reliés par ||. Zéro résultat signifie que vos labels utilisent déjà une syntaxe v3 valide et que la migration se limite à la configuration statique et au tag de l’image. Une page entière de résultats est également un bon moment pour vous demander si ce proxy est toujours adapté à ce serveur ; la comparaison entre Traefik, Nginx et Caddy met le coût de cette réécriture en regard de ce que les deux autres vous demandent pour chaque application.
Ce qui reste inchangé
Les points d’entrée et leur redirection HTTP vers HTTPS, les résolveurs ACME avec leurs deux types de challenge, exposedByDefault, les labels des routeurs et des services, loadbalancer.server.port et le tableau de bord fonctionnent en v3 comme en v2. Vos certificats sont également conservés, car v3 continue de lire le acme.json créé par v2. Sauvegardez tout de même ce fichier avant de commencer : un rollback qui le perd vous expose directement à la limite de débit de Let’s Encrypt concernant les certificats en double :
cp ./letsencrypt/acme.json ./letsencrypt/acme.json.v2-backupLa procédure de migration
Étape 1 : verrouillez la version utilisée aujourd’hui. Remplacez chaque tag traefik:latest ou traefik:v2 par la release exacte que vous utilisez, par exemple traefik:v2.11, puis versionnez l’ensemble du répertoire Compose dans git. Chaque étape suivante pourra être annulée avec un checkout. Si recréer un service unique avec docker compose up -d <service> ne vous est pas encore familier, le guide sur les bases de Docker Compose présente les opérations utilisées dans cette migration.
Étape 2 : nettoyez la configuration statique et activez le mode de compatibilité. Supprimez toutes les options abandonnées par v3 (pilot, swarmMode, tls.caOptional, experimental.http3), puis indiquez à v3 d’interpréter par défaut les règles comme une syntaxe v2. Dans traefik.yml :
core:
defaultRuleSyntax: v2Vous pouvez aussi utiliser un flag dans la liste compose command: : --core.defaultRuleSyntax=v2. Le mode de compatibilité ne concerne que la syntaxe des règles. Il ne rétablit pas les options supprimées et ne renomme pas les middlewares à votre place.
Étape 3 : appliquez les renommages de middlewares tout en restant sous v2.11. Recherchez les anciens noms dans vos fichiers Compose : grep -rn ipwhitelist docker-compose*.yml. Modifiez chaque label ipwhitelist en ipallowlist, puis recréez ces services avec docker compose up -d. v2.11 fournit déjà le middleware IPAllowList. Les labels renommés fonctionnent donc avant la migration, et l’avertissement d’obsolescence d’IPWhiteList disparaît de vos journaux v2. Les releases antérieures à v2.11 ne connaissent pas le nouveau nom. Si vous avez verrouillé une ancienne version v2 à l’étape 1, passez d’abord à traefik:v2.11. (Si un ancien nom reste présent, la v3 actuelle l’accepte encore comme alias obsolète. La liste continue donc de s’appliquer. Corrigez-le lors du passage suivant plutôt qu’à 2 h du matin.)
Étape 4 : modifiez le tag de l’image. Définissez l’image Traefik sur la release v3 actuelle, traefik:v3.7 au 11 octobre 2026 (v3.7.14 est le dernier patch), puis :
docker compose up -d
docker compose logs -f traefikLe mode de compatibilité étant activé, vos règles v2 continuent de fonctionner. Les renommages de middlewares ayant déjà été appliqués sous v2.11, ces routers démarrent correctement. Un journal sain ne contient aucune ligne field not found ni aucune ligne does not exist.
Évaluez précisément l’interruption possible pendant cette étape. Un router qui référence un nom de middleware que v3 ne connaît réellement pas (à cause d’une faute de frappe ou d’une option supprimée) est indisponible dès le démarrage de la nouvelle version de Traefik, jusqu’à la correction de ses labels et à la recréation de son conteneur applicatif. Si une route ne peut réellement subir aucune interruption, retirez le middleware suspect du label middlewares de ce router avant la migration, puis ajoutez-le de nouveau après. Décidez à l’avance si cette route peut fonctionner sans ce middleware pendant la minute nécessaire.
Étape 5 : migrez les règles service par service. Traitez une application à la fois : réécrivez sa règle avec la syntaxe v3, recréez uniquement ce service avec docker compose up -d app, puis testez-le avant de poursuivre. Si une règle ne peut pas encore être réécrite, ajoutez le label d’échappement traefik.http.routers.app.ruleSyntax=v2 à ce router uniquement, puis continuez.
Étape 6 : désactivez le mode de compatibilité. Lorsque toutes les règles utilisent la syntaxe v3, supprimez defaultRuleSyntax et tous les labels ruleSyntax, redémarrez Traefik et vérifiez que chaque router apparaît toujours en vert dans le dashboard. Ne conservez pas durablement le mode de compatibilité : Traefik a marqué ces deux options comme obsolètes dans v3.4 et les supprimera dans la prochaine version majeure. Elles servent de transition, pas de configuration cible.
Avant et après : les labels d’un service
Voici une application qui cumule tous les changements courants : un Host multivaleur, un placeholder PathPrefix et un middleware ipWhiteList. Le bloc v2 :
app:
image: app:1.4
restart: unless-stopped
networks:
- proxy
labels:
- traefik.enable=true
- traefik.http.routers.app.rule=Host(`app.example.com`,`www.example.com`) && PathPrefix(`/api/{version:v[0-9]+}`)
- traefik.http.routers.app.entrypoints=websecure
- traefik.http.routers.app.tls.certresolver=le
- traefik.http.routers.app.middlewares=office
- traefik.http.middlewares.office.ipwhitelist.sourcerange=10.0.0.0/24
- traefik.http.services.app.loadbalancer.server.port=8080Et le même service migré vers la v3 :
app:
image: app:1.4
restart: unless-stopped
networks:
- proxy
labels:
- traefik.enable=true
- traefik.http.routers.app.rule=(Host(`app.example.com`) || Host(`www.example.com`)) && PathRegexp(`^/api/v[0-9]+`)
- traefik.http.routers.app.entrypoints=websecure
- traefik.http.routers.app.tls.certresolver=le
- traefik.http.routers.app.middlewares=office
- traefik.http.middlewares.office.ipallowlist.sourcerange=10.0.0.0/24
- traefik.http.services.app.loadbalancer.server.port=8080Deux labels ont changé. La règle a séparé son Host multivaleur en deux matchers reliés par || et a remplacé le placeholder par PathRegexp. Le label du middleware a remplacé ipwhitelist par ipallowlist. L’entrypoint, le certificate resolver, la liaison entre le router et le middleware ainsi que le port du service n’ont pas changé.
Tester chaque service avec le dashboard
Après chaque basculement, ouvrez la page des routeurs HTTP du dashboard. Tous les routeurs doivent être verts. Un routeur marqué d’une erreur indique précisément le problème rencontré. Il s’agit généralement d’un middleware qui n’existe plus sous son nouveau nom ou d’une règle que v3 ne peut pas analyser. Vérifiez ensuite le résultat depuis l’extérieur, un nom d’hôte à la fois :
curl -sI https://app.example.com/api/v1/statusUn 200 ou la redirection habituelle de votre application signifie que le routage et TLS fonctionnent toujours. Un 404 renvoyé par Traefik signifie que le routeur n’a pas démarré. Retournez au dashboard et consultez son erreur. Gardez docker compose logs -f traefik ouvert dans un second terminal pendant l’opération. Chaque erreur d’analyse y apparaît dès qu’un conteneur redémarre.
Honnêteté du rollback
Conservez le fichier Compose v2, sa configuration statique et la sauvegarde acme.json jusqu’à ce que tous les services soient routés sur v3 et aient été testés en conditions réelles. Pour effectuer un rollback, revenez au commit précédant la migration, puis exécutez docker compose up -d. Vous devez restaurer l’ensemble du fichier, et pas seulement le tag de l’image, car la syntaxe propre à v3 est invalide avec v2, tout comme la syntaxe v2 était invalide avec v3 : un matcher PathRegexp ne pourra pas y être analysé. Les labels ipallowlist renommés fonctionnent avec v2.11, mais pas avec une version v2 antérieure, qui ne connaît pas ce nouveau nom. Si acme.json a été perdu ou endommagé en cours de route, restaurez la copie de sauvegarde avant de démarrer v2. Le rollback n’utilisera ainsi pas votre quota Let’s Encrypt en réémettant cinq certificats simultanément.
FAQ
Dois-je réécrire toutes les règles de routeur pour Traefik v3 ?
Non. Une règle Host(app.example.com) simple écrite avec des accents graves est valide dans les deux versions et couvre la plupart des configurations Compose. La réécriture est nécessaire uniquement lorsqu’une règle utilise des fonctionnalités propres à v2 : des expressions régulières ou des espaces réservés dans Path et PathPrefix, plusieurs noms d’hôte dans un même Host(), ou les matchers Headers, HeadersRegexp et HostHeader, qui ont été supprimés.
Que devient ipWhiteList dans Traefik v3 ?
Il a été renommé ipAllowList. La configuration reste inchangée. Ainsi, un label v2 comme traefik.http.middlewares.office.ipwhitelist.sourcerange=10.0.0.0/24 devient la même ligne avec ipallowlist. v2.11 accepte déjà le nouveau nom. Vous pouvez donc le renommer avant la mise à niveau. Les versions v3 actuelles, y compris v3.7, acceptent encore l’ancien nom comme alias obsolète. Un label non renommé continue donc d’appliquer l’allowlist, avec seulement un avertissement dans le journal. Considérez cela comme un délai, pas comme une raison de ne pas effectuer le renommage : les noms obsolètes peuvent être supprimés dans une prochaine release. En revanche, un nom de middleware que Traefik ne connaît réellement pas provoque une erreur explicite, avec une erreur de routeur et une réponse 404. Le dashboard affiche l’erreur et les requêtes vers ce nom d’hôte renvoient 404.
Traefik v3 peut-il encore lire la syntaxe des règles v2 ?
Oui. Définissez core.defaultRuleSyntax: v2 dans la configuration statique pour conserver la syntaxe v2 par défaut pendant la migration. Utilisez ensuite le label ruleSyntax=v2 au niveau de chaque routeur pour les derniers routeurs concernés, après avoir rétabli la nouvelle syntaxe par défaut. Ces deux options sont temporaires : Traefik les a déclarées obsolètes dans v3.4 et les supprimera dans la prochaine version majeure.
Mes certificats Let's Encrypt survivront-ils à la mise à niveau ?
Oui. Traefik v3 continue de lire le fichier acme.json écrit par v2. Les certificats ne sont donc pas réémis uniquement parce que le binaire a changé. Copiez tout de même ce fichier dans un emplacement sûr avant de commencer. Un rollback ou la suppression d’un volume qui fait perdre acme.json impose de réémettre tous les certificats en une seule fois. Let's Encrypt autorise seulement cinq certificats en double par semaine pour le même ensemble de noms d’hôte.
Pourquoi Traefik v3 ne démarre-t-il plus après la mise à niveau ?
Presque toujours parce que la configuration statique contient encore une option supprimée dans v3. Traefik refuse de démarrer lorsqu’une option n’est pas reconnue. Pour les options obsolètes connues (pilot, providers.docker.swarmMode, experimental.http3 et tls.caOptional des providers), le journal indique la cause, puis affiche incompatible deprecated install configuration option found (incompatible deprecated static option found dans v3.4 et les versions antérieures). Pour tout ce que v3 n’a jamais reconnu, par exemple une faute de frappe, il affiche field not found avec le nœud concerné. Supprimez ou remplacez chaque option, puis redémarrez le conteneur.