Migrar Traefik v2 a v3: errores y cambios clave
Traefik v3 no inicia con swarmMode ni pilot en la configuración estática. Corrige el error de opción deprecated incompatible y migra las reglas sin cambiar todo de una vez.
Qué cambia entre Traefik v2 y v3
La migración de Traefik v2 a v3 consiste principalmente en cambiar nombres. El cambio más conocido es que el middleware ipWhiteList pasa a llamarse ipAllowList. Además, v3 endurece la sintaxis de las reglas de los routers: PathPrefix pierde sus funciones de expresiones regulares y se renombran o eliminan varios matchers. También elimina algunos proveedores y opciones. El resto sigue funcionando: los entrypoints, la configuración de certificados ACME, el flujo de trabajo basado en etiquetas de Docker y su acme.json se mantienen. v3 también incluye un modo de compatibilidad que mantiene la sintaxis de reglas de v2. Así puede actualizar primero el binario y reescribir las reglas servicio por servicio, en lugar de hacerlo todo en una tarde con riesgo.
Esta guía presupone la configuración de Docker Compose basada en etiquetas descrita en la guía del proxy inverso Traefik. Esa página usa v3 de forma nativa. Esta guía está dirigida al servidor que todavía ejecuta una etiqueta traefik:v2.
Los cambios de nombre y las eliminaciones
ipWhiteListahora esipAllowList, tanto para el middleware HTTP como para el middleware TCP. Las opciones internas no cambian, por lo quesourcerangemantiene exactamente el mismo significado. Las versiones actuales de v3, incluida v3.7, todavía aceptan el nombre antiguo como alias obsoleto y siguen aplicando la lista; además, registran una advertencia de obsolescencia. Por tanto, este cambio de nombre no deja ningún servicio fuera de servicio al actualizar. Aun así, cambie el nombre: el antiguo está obsoleto y v2.11 ya entiendeipAllowList, por lo que puede aplicar el cambio antes de actualizar.
providers.docker.swarmMode=trueha desaparecido. Swarm tiene ahora su propio proveedor, configurado comoproviders.swarm.endpoint.- La sección
pilotha desaparecido por completo. experimental.http3ha desaparecido. HTTP/3 se habilita directamente en el entrypoint.tls.caOptionalha desaparecido de los proveedores y del middleware forwardAuth. Si ese middleware está delante de un SSO Authentik autohospedado, eliminar la líneacaOptionalcompleta la migración, porque la dirección de forwardAuth, las cabeceras de confianza y el outpost situado detrás siguen funcionando igual en v3.- El proveedor de métricas InfluxDB v1, el proveedor de Rancher y el proveedor de Marathon han desaparecido.
- El tracing se ha trasladado a OpenTelemetry. Los backends de tracing dedicados, incluidas las integraciones con Jaeger y Zipkin, han desaparecido, y v3 exporta OTLP (el protocolo de OpenTelemetry) en su lugar.
- Las opciones obsoletas
ssl*del middleware headers (sslRedirect,sslHosty las demás) han desaparecido. Las redirecciones del entrypoint y el middleware redirectScheme las han sustituido.
Estas eliminaciones son más importantes de lo que parece, porque Traefik se niega a iniciar cuando su configuración estática contiene una opción que ha eliminado o que no reconoce. Una línea pilot, swarmMode, experimental.http3 o tls.caOptional de un proveedor que haya quedado atrás detiene el contenedor durante el arranque: Traefik primero registra una línea que identifica la opción sobrante (por ejemplo, la opción tls.CAOptional del proveedor Docker se ha eliminado en v3) y después falla con incompatible deprecated install configuration option found. Hasta la versión v3.4, las versiones expresan ese último mensaje como incompatible deprecated static option found. Una opción que Traefik nunca ha reconocido, como un error tipográfico, lo detiene con field not found y el nodo tampoco inicia. Limpie la configuración estática antes de cambiar la etiqueta de la imagen.
Un nombre de middleware que Traefik realmente no reconoce (por un error tipográfico o porque se ha eliminado en lugar de conservarse como alias) falla de otra forma: el router que lo referencia se carga con un error en vez de crear la ruta, el dashboard lo marca y la API informa de middleware "offce@docker" does not exist. Las peticiones a ese nombre de host reciben un 404 porque el router nunca llegó a iniciarse. Tenga en cuenta que ipwhitelist NO pertenece a esta categoría en la versión v3 actual: se conserva como alias obsoleto, por lo que una etiqueta sin cambiar sigue funcionando sin mostrar errores.
Cambian la sintaxis de las reglas
Las reglas permiten realizar las reescrituras. Estos son los cambios en v3:
- Las comillas no cambian. Ambas versiones aceptan los valores de las reglas entre acentos graves o comillas dobles escapadas, y rechazan las comillas simples. Por tanto, Host(
app.example.com) y Host("app.example.com") con comillas dobles escapadas siguen siendo válidos. PathPrefixya no admite expresiones regulares ni marcadores de posición con el estilo de{id}. Una regla de v2 como PathPrefix(/api/{version:v[0-9]+}) debe convertirse en un comparadorPathRegexpescrito con la sintaxis de expresiones regulares de Go.- Los comparadores ahora aceptan un único valor. v2 permitía Host(
app.example.com,www.example.com); v3 requiere Host(app.example.com) || Host(www.example.com). Las excepciones sonHeader,HeaderRegexp,QueryyQueryRegexp, que siguen aceptando un nombre y un valor. HeadersyHeadersRegexpcambian de nombre aHeaderyHeaderRegexp.HostHeaderse elimina. UseHost, que en v3 coincide con lo mismo.- Hay dos comparadores nuevos:
PathRegexpyQueryRegexp.ClientIP, que permite comparar la dirección del cliente dentro de una regla, ya existía en v2.11 y se mantiene sin cambios.
La ventaja es que una regla Host(app.example.com) sencilla escrita con acentos graves ya tiene una sintaxis válida en v3. La mayoría de las configuraciones pequeñas de Compose usan exactamente este formato, por lo que la mayoría de las etiquetas migran sin modificar las reglas.
Audite sus etiquetas antes de empezar
Puede medir el alcance de la migración con una búsqueda, porque cada cambio incompatible en una etiqueta deja un patrón que grep puede encontrar:
grep -rnE 'ipwhitelist|HostHeader|Headers\(|PathPrefix\(`[^`]*\{|Host\(`[^`]*`,' docker-compose*.ymlCada coincidencia corresponde a una línea que debe editar. ipwhitelist se convierte en ipallowlist. HostHeader se convierte en Host. Headers se convierte en Header. Un marcador de posición {...} dentro de PathPrefix se convierte en un comparador PathRegexp. Una coma dentro de Host() se convierte en dos comparadores Host() unidos mediante ||. Cero coincidencias significa que sus etiquetas ya usan una sintaxis v3 válida y que la migración se reduce a la configuración estática y a la etiqueta de imagen. Una pantalla llena de coincidencias también es un buen momento para preguntarse si este sigue siendo el proxy adecuado para el servidor. cómo se compara Traefik con Nginx y Caddy relaciona ese coste de reescritura con lo que los otros dos le exigen por aplicación.
Qué permanece igual
Los puntos de entrada y su redirección de HTTP a HTTPS, los resolutores ACME con ambos tipos de desafío, exposedByDefault, las etiquetas del router y del servicio, loadbalancer.server.port y el panel siguen funcionando en v3 igual que en v2. Los certificados también se conservan porque v3 sigue leyendo el acme.json que escribió v2. De todos modos, haga una copia de seguridad del archivo antes de empezar. Una reversión que lo pierda activa directamente el límite de tasa de Let's Encrypt para certificados duplicados:
cp ./letsencrypt/acme.json ./letsencrypt/acme.json.v2-backupLa ruta de migración
Paso 1: fije lo que ejecuta actualmente. Cambie cualquier etiqueta traefik:latest o traefik:v2 por la versión exacta que utiliza, por ejemplo traefik:v2.11, y confirme todo el directorio de compose en git. Todos los pasos posteriores se podrán revertir con un checkout. Si todavía no puede recrear un servicio individual con docker compose up -d <service> de forma habitual, la guía básica de Docker Compose explica las operaciones en las que se basa esta migración.
Paso 2: limpie la configuración estática y active el modo de compatibilidad. Elimine todas las opciones que v3 eliminó (pilot, swarmMode, tls.caOptional, experimental.http3) y haga que v3 trate las reglas como sintaxis de v2 de forma predeterminada. En traefik.yml:
core:
defaultRuleSyntax: v2También puede especificarlo como una opción en la lista compose command:: --core.defaultRuleSyntax=v2. El modo de compatibilidad sólo cubre la sintaxis de las reglas. No recupera las opciones eliminadas ni cambia el nombre de los middlewares.
Paso 3: aplique los cambios de nombre de los middlewares mientras sigue en v2.11. Busque los nombres antiguos en los archivos compose: grep -rn ipwhitelist docker-compose*.yml. Cambie cada etiqueta ipwhitelist por ipallowlist y recree esos servicios con docker compose up -d. v2.11 ya incluye el middleware IPAllowList, por lo que las etiquetas renombradas funcionan antes del cambio, y la advertencia de obsolescencia de IPWhiteList desaparece de los registros de v2. Las versiones anteriores a v2.11 no conocen el nombre nuevo. Si fijó una versión v2 anterior en el paso 1, actualícela primero a traefik:v2.11. Si queda alguna etiqueta antigua, la v3 actual todavía acepta ese nombre como alias obsoleto, por lo que la lista seguirá aplicándose. Corríjala en la siguiente pasada y no a las 2am.
Paso 4: cambie la etiqueta de la imagen. Establezca la imagen de Traefik en la versión actual de v3, traefik:v3.7 a fecha de 11 October 2026 (v3.7.14 es el último parche), y ejecute:
docker compose up -d
docker compose logs -f traefikComo el modo de compatibilidad está activo, las reglas de v2 seguirán coincidiendo. Además, como los cambios de nombre de los middlewares ya se aplicaron en v2.11, esos routers se iniciarán correctamente. Un registro correcto no contiene ninguna línea field not found ni ninguna línea does not exist.
Sea realista sobre la ventana de riesgo que abre este paso. Un router que haga referencia a un nombre de middleware que v3 realmente no reconoce, ya sea por un error tipográfico o por una opción eliminada, estará inactivo desde el momento en que se inicie la nueva versión de Traefik hasta que corrija sus etiquetas y recree el contenedor de la aplicación. Si una ruta no puede quedar inactiva, elimine el middleware problemático de la etiqueta middlewares de ese router antes del cambio, vuelva a añadirlo después y decida de antemano si la ruta puede funcionar sin él durante ese minuto.
Paso 5: migre las reglas servicio por servicio. Trabaje con una aplicación cada vez: reescriba su regla con la sintaxis de v3, recree sólo ese servicio con docker compose up -d app y pruébelo antes de continuar. Si un servicio tiene una regla que todavía no puede reescribir, añada a ese router la etiqueta de escape traefik.http.routers.app.ruleSyntax=v2 y continúe.
Paso 6: desactive el modo de compatibilidad. Cuando todas las reglas utilicen la sintaxis de v3, elimine defaultRuleSyntax y cualquier etiqueta ruleSyntax, reinicie Traefik y confirme que todos los routers siguen apareciendo en verde en el dashboard. No mantenga el modo de compatibilidad activo de forma permanente: Traefik declaró obsoletas ambas opciones en v3.4 y las eliminará en la siguiente versión principal. Son un puente, no el destino.
Antes y después: las etiquetas de un servicio
Esta es una aplicación que incorpora todos los cambios conocidos a la vez: un Host con varios valores, un marcador de posición PathPrefix y un middleware ipWhiteList. El bloque de 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=8080Y el mismo servicio migrado a 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=8080Cambiaron dos etiquetas. La regla dividió su Host con varios valores en dos matchers unidos mediante || y sustituyó el marcador de posición por PathRegexp. La etiqueta del middleware sustituyó ipwhitelist por ipallowlist. El entrypoint, el certificate resolver, la conexión entre el router y el middleware, y el puerto del servicio no cambiaron.
Pruebe cada servicio con el dashboard
Después de cada cambio, abra la página de routers HTTP del dashboard. Todos los routers deben aparecer en verde. Un router con una insignia de error muestra el problema exacto. Normalmente se trata de un middleware que no existe con su nuevo nombre o de una regla v3 que no se puede analizar. Después, confirme el funcionamiento desde fuera, un nombre de host cada vez:
curl -sI https://app.example.com/api/v1/statusUn 200 o la redirección habitual de su aplicación indica que el enrutamiento y TLS siguen funcionando. Un 404 de Traefik indica que el router no se inició. Vuelva al dashboard y lea el error. Mantenga docker compose logs -f traefik abierto en un segundo terminal mientras trabaja, porque todos los errores de análisis aparecen allí en cuanto se reinicia un contenedor.
Sinceridad del rollback
Conserve el archivo compose de v2, su configuración estática y la copia de seguridad de acme.json hasta que todos los servicios se enruten mediante v3 y se hayan probado en condiciones reales. Para hacer rollback, debe recuperar el commit anterior a la migración y ejecutar docker compose up -d. Debe recuperar el archivo completo, no sólo la etiqueta de la imagen, porque la sintaxis exclusiva de v3 no es válida en v2, del mismo modo que la sintaxis de v2 no era válida en v3: un matcher PathRegexp no se puede analizar allí. Las etiquetas ipallowlist renombradas funcionan en v2.11, pero no en ninguna versión anterior de v2, que no reconoce el nombre nuevo. Si acme.json se perdió o resultó dañado durante el proceso, restaure la copia de seguridad antes de iniciar v2. Así evitará consumir el límite de solicitudes de Let's Encrypt al volver a emitir cinco certificados a la vez.
FAQ
¿Tengo que reescribir todas las reglas de los routers para Traefik v3?
No. Una regla simple Host(app.example.com) escrita con comillas invertidas es válida en ambas versiones y cubre la mayoría de las configuraciones de Compose. Sólo es necesario reescribir las reglas que usaban funciones exclusivas de v2: expresiones regulares o marcadores de posición dentro de Path y PathPrefix, varios nombres de host dentro de un mismo Host(), o los matchers eliminados Headers, HeadersRegexp y HostHeader.
¿Qué ocurrió con ipWhiteList en Traefik v3?
Se cambió su nombre a ipAllowList, pero la configuración interna no cambió. Por tanto, una etiqueta de v2 como traefik.http.middlewares.office.ipwhitelist.sourcerange=10.0.0.0/24 pasa a ser la misma línea con ipallowlist. v2.11 ya acepta el nombre nuevo, así que puede cambiarlo antes de actualizar. Las versiones actuales de v3, incluida v3.7, todavía aceptan el nombre antiguo como alias obsoleto. Por eso, una etiqueta que no se haya cambiado sigue aplicando la lista de permitidos y sólo genera una advertencia en el registro. Considérelo una situación temporal, no un motivo para omitir el cambio de nombre: una versión puede eliminar los nombres obsoletos. En cambio, si Traefik no reconoce el nombre de un middleware, el fallo es inmediato: muestra un error del router y devuelve 404. El dashboard muestra el error y las peticiones a ese nombre de host devuelven 404.
¿Traefik v3 todavía puede leer la sintaxis de reglas de v2?
Sí. Establezca core.defaultRuleSyntax: v2 en la configuración estática para mantener la sintaxis de v2 como valor predeterminado durante la migración. Después de volver a cambiar el valor predeterminado, use la etiqueta ruleSyntax=v2 por router para los casos individuales que queden pendientes. Considere ambas opciones temporales: Traefik las marcó como obsoletas en v3.4 y las eliminará en la siguiente versión principal.
¿Mis certificados de Let's Encrypt seguirán disponibles después de la actualización?
Sí. Traefik v3 sigue leyendo el archivo acme.json que escribió v2, por lo que los certificados no se vuelven a emitir sólo porque haya cambiado el binario. Aun así, copie el archivo en un lugar seguro antes de empezar. Una reversión o un volumen eliminado que pierda acme.json obliga a volver a emitir todos los certificados a la vez. Let's Encrypt permite como máximo cinco certificados duplicados por semana para el mismo conjunto de nombres de host.
¿Por qué Traefik v3 no arranca después de la actualización?
Casi siempre se debe a que la configuración estática todavía contiene una opción que v3 eliminó. Traefik no arranca si encuentra opciones que no reconoce. Para las opciones antiguas conocidas (pilot, providers.docker.swarmMode, experimental.http3 y tls.caOptional de los proveedores), el registro identifica la causa y después muestra incompatible deprecated install configuration option found (incompatible deprecated static option found en v3.4 y anteriores). Para cualquier elemento que v3 nunca haya reconocido, como un error tipográfico, muestra field not found junto con el nodo. Elimine o sustituya cada opción y vuelva a iniciar el contenedor.