SSD Nodes Learn
Guías Matt ConnorPor Matt Connor · Actualizado 2026-07-24

migrar de traefik v2 a v3 cambios y errores

Evita errores de configuración estática al migrar a Traefik v3. Aprende por qué fallan swarmMode y pilot y cómo renombrar ipWhiteList a ipAllowList con éxito.

Cambios entre Traefik v2 y v3

La migración de Traefik v2 a v3 consiste principalmente en renombrar componentes. El cambio más relevante es que el middleware ipWhiteList ahora se llama ipAllowList. Además, la v3 restringe la sintaxis de las reglas del router (PathPrefix pierde sus funciones de regex, y varios matchers han sido renombrados o eliminados). También se eliminan algunos providers y opciones, pero el resto funciona igual: los entrypoints, la configuración de certificados ACME, el flujo de trabajo con labels de Docker y su acme.json se mantienen. La v3 incluye un modo de compatibilidad que permite usar la sintaxis de reglas de la v2. Esto permite actualizar el binario primero y reescribir las reglas de cada servicio individualmente para evitar riesgos.

Esta guía asume el uso de Docker Compose basado en labels descrito en la guía del reverse proxy de Traefik. Esa página es nativa de la v3; esta es para sistemas que aún ejecutan una etiqueta traefik:v2.

Renombramientos y eliminaciones

  • ipWhiteList ahora es ipAllowList, tanto para el middleware de HTTP como para el de TCP. Las opciones internas no han cambiado, por lo que sourcerange mantiene su significado exacto. Las versiones actuales de v3, incluida la v3.5, todavía aceptan el nombre antiguo como un alias deprecado y mantienen la lista; este renombramiento no causará fallos inmediatos. Renómbrelo de todos modos: la eliminación del alias está programada y desaparecerá de la lista de deprecación sin avisos.
  • providers.docker.swarmMode=true ha sido eliminado. Swarm ahora tiene su propio proveedor, configurado como providers.swarm.endpoint.
  • La sección pilot ha sido eliminada por completo.
  • experimental.http3 ha sido eliminado. HTTP/3 se habilita directamente en el entrypoint.
  • tls.caOptional ha sido eliminado de los proveedores y del middleware forwardAuth.
  • Se han eliminado el proveedor de métricas InfluxDB v1, el proveedor Rancher y el proveedor Marathon.
  • Tracing se ha movido a OpenTelemetry. Los backends de tracing dedicados, incluyendo las integraciones con Jaeger y Zipkin, han sido eliminados; la v3 exporta OTLP (el protocolo OpenTelemetry) en su lugar.
  • Las opciones deprecadas ssl* dentro del middleware de headers (sslRedirect, sslHost y el resto) han sido eliminadas. Las redirecciones del entrypoint y el middleware redirectScheme las han reemplazado.

Estas eliminaciones son más críticas de lo que parecen, ya que Traefik falla al iniciar si su configuración estática contiene una opción desconocida. Una línea residual de pilot o swarmMode detiene el contenedor al arrancar con un mensaje de incompatible deprecated static option found que identifica la opción; una opción que Traefik desconozca totalmente (un error tipográfico o tls.caOptional) detiene el proceso con un field not found. Limpie la configuración estática antes de cambiar la etiqueta de la imagen.

Un nombre de middleware que Traefik realmente no reconozca (un error tipográfico o un nombre eliminado en lugar de alias) falla de forma distinta: el router que lo referencia carga con un error en lugar de una ruta, el dashboard lo marca y la API reporta middleware "offce@docker" does not exist. Las peticiones a ese hostname recibirán un 404 porque el router nunca se inició. Tenga en cuenta que ipwhitelist NO pertenece a esta categoría en la v3 actual: sobrevive como un alias deprecado, por lo que una etiqueta no renombrada seguirá funcionando sin avisos.

Cambios en la sintaxis de las reglas

Las reglas son donde ocurre la reescritura real. Los cambios en v3:

  • Se requieren backticks para los valores dentro de los matchers. v2 también aceptaba comillas dobles; v3 no, por lo que Host("app.example.com") debe convertirse en Host(app.example.com).
  • PathPrefix ya no reconoce expresiones regulares ni placeholders estilo {id}. Una regla de v2 como PathPrefix(/api/{version:v[0-9]+}) debe convertirse en un matcher PathRegexp escrito en sintaxis de expresiones regulares de Go.
  • Los matchers 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 son Header, HeaderRegexp, Query y QueryRegexp, que siguen requiriendo un nombre más un valor.
  • Headers y HeadersRegexp se renombran a Header y HeaderRegexp.
  • HostHeader ha sido eliminado. Use Host, que coincide con lo mismo en v3.
  • Hay dos matchers nuevos: QueryRegexp y ClientIP para coincidir con la dirección del cliente dentro de una regla.

La buena noticia: una regla simple Host(app.example.com) escrita con backticks ya es sintaxis válida de v3. La mayoría de las configuraciones pequeñas de Compose usan exactamente eso, lo que significa que la mayoría de las etiquetas migran sin necesidad de editar las reglas.

Audite sus etiquetas antes de comenzar

Puede medir el tamaño de su migración con una sola búsqueda, ya que cada cambio de etiqueta que rompa la compatibilidad deja un patrón que grep puede encontrar:

grep -rnE 'ipwhitelist|HostHeader|Headers\(|PathPrefix\(`[^`]*\{|Host\(`[^`]*`,' docker-compose*.yml

Cada coincidencia es una línea que debe editar. ipwhitelist pasa a ser ipallowlist. HostHeader pasa a ser Host. Headers pasa a ser Header. Un marcador de posición {...} dentro de PathPrefix pasa a ser un comparador PathRegexp. Una coma dentro de Host() pasa a ser dos comparadores Host() unidos por ||. Cero coincidencias significa que sus etiquetas ya usan la sintaxis válida de v3, y la migración se reduce a la configuración estática más la etiqueta de la imagen.

Lo que permanece igual

Los entrypoints y su redirección de HTTP a HTTPS, los ACME resolvers con ambos tipos de challenge, exposedByDefault, las etiquetas de router y service, loadbalancer.server.port y el dashboard funcionan en v3 igual que en v2. Los certificados también se mantienen, ya que v3 sigue leyendo el acme.json que escribió v2. Realice una copia de seguridad del archivo antes de comenzar; si una reversión (rollback) lo pierde, entrará directamente en el límite de tasa (rate limit) de certificados duplicados de Let's Encrypt:

cp ./letsencrypt/acme.json ./letsencrypt/acme.json.v2-backup

El proceso de migración

Paso 1: fije la versión actual. Cambie cualquier etiqueta traefik:latest o traefik:v2 por la versión exacta que esté utilizando, por ejemplo traefik:v2.11, y realice un commit de todo el directorio de compose en git. Todos los pasos posteriores serán reversibles mediante un checkout. Si recrear un único servicio con docker compose up -d <service> no es un proceso habitual para usted, la guía básica de Docker Compose cubre las operaciones necesarias para esta migración.

Paso 2: limpie la configuración estática y active el modo de compatibilidad. Elimine todas las opciones eliminadas en v3 (pilot, swarmMode, tls.caOptional, experimental.http3), y luego configure v3 para que trate las reglas como sintaxis de v2 por defecto. En traefik.yml:

core:
  defaultRuleSyntax: v2

O como un flag en la lista de compose command:: --core.defaultRuleSyntax=v2. El modo de compatibilidad solo cubre la sintaxis de las reglas. No restaura opciones eliminadas ni renombra middlewares automáticamente.

Paso 3: prepare el renombramiento de los middlewares. Busque en sus archivos compose los nombres antiguos: grep -rn ipwhitelist docker-compose*.yml. Edite cada etiqueta ipwhitelist por ipallowlist, pero no aplique el cambio todavía, ya que el nuevo nombre no existe en v2. Estas ediciones se aplicarán junto con el cambio del siguiente paso. (Si algún nombre se pasa por alto, la v3 actual seguirá aceptando el nombre antiguo como un alias deprecado, por lo que la lista seguirá fallando; corríjalo en la siguiente pasada en lugar de hacerlo a las 2 a.m.)

Paso 4: cambie la etiqueta de la imagen. Establezca la imagen de Traefik en la versión actual de v3, traefik:v3.5 al momento de escribir esto, y luego:

docker compose up -d
docker compose logs -f traefik

Debido a que el modo de compatibilidad está activo, sus reglas de v2 seguirán funcionando, y como up -d también recreó los servicios cuyas etiquetas de middleware renombró, esos routers se iniciarán correctamente. Un log sin errores no debe tener líneas con field not found ni con does not exist.

Considere seriamente el tiempo de inactividad que este paso genera. Un router que haga referencia a un nombre de middleware que v3 no reconoce (por un error tipográfico o una opción eliminada) dejará de funcionar desde que el nuevo Traefik se inicie hasta que se recree el contenedor de su aplicación; en un solo equipo, esto es el tiempo que docker compose up -d tarda en procesar la lista. Si una ruta no puede permitirse ni un segundo de inactividad, elimine el middleware renombrado de la etiqueta middlewares de ese router antes del cambio y vuelva a añadirlo después; decida de antemano si esa ruta puede funcionar sin su lista de IPs permitidas durante ese intervalo.

Paso 5: migre las reglas servicio por servicio. Trabaje con una aplicación a la vez: reescriba su regla a sintaxis v3, recree únicamente ese servicio con docker compose up -d app y pruébelo antes de continuar. Si un servicio tiene una regla que aún no puede reescribir, asigne 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 usen sintaxis v3, elimine defaultRuleSyntax y cualquier etiqueta ruleSyntax, reinicie Traefik y confirme que todos los routers sigan apareciendo en verde en el dashboard. No mantenga activado el modo de compatibilidad: Traefik marcó ambas opciones como deprecadas en la v3.4 y las eliminará en la próxima versión mayor; son un puente, no un destino final.

Antes y después: etiquetas de un servicio

Este ejemplo muestra una aplicación con múltiples cambios simultáneos: un Host de valores múltiples, un marcador de posición PathPrefix y un middleware ipWhiteList. El bloque 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=8080

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=8080

Dos etiquetas cambiaron. La regla dividió su Host de valores múltiples en dos selectores unidos por || y reemplazó el marcador de posición por PathRegexp. La etiqueta del middleware cambió ipwhitelist por ipallowlist. El entrypoint, el certificate resolver, la conexión router-middleware y el puerto del servicio no cambiaron.

Pruebe cada servicio con el dashboard

Después de cada cambio, abra la página de HTTP routers del dashboard. Todos los routers deben aparecer en verde. Un router con una insignia de error indica su problema exacto; generalmente es un middleware que no existe bajo su nuevo nombre o una regla que v3 no puede procesar. Luego, confirme desde fuera, un hostname a la vez:

curl -sI https://app.example.com/api/v1/status

Un 200 o la redirección normal de su app significa que tanto el routing como el TLS funcionan correctamente. Un 404 de Traefik significa que el router no se inició; vuelva al dashboard y lea el error. Mantenga docker compose logs -f traefik abierto en una segunda terminal mientras trabaja, ya que cualquier error de procesamiento se registra allí en cuanto se reinicia un contenedor.

Integridad del rollback

Conserve el archivo compose de la v2, su configuración estática y el backup acme.json hasta que todos los servicios utilicen la v3 y se hayan probado en producción. Realizar un rollback consiste en hacer checkout del commit previo a la migración y ejecutar docker compose up -d. Debe utilizarse el archivo completo y no solo la etiqueta de la imagen; las etiquetas exclusivas de la v3 causarán errores en la v2, de la misma forma que las etiquetas de la v2 fallan en la v3: ipallowlist no existe en la v2 y un matcher PathRegexp tampoco podrá procesarse allí. Si acme.json se perdió o dañó durante el proceso, restaure la copia de seguridad antes de iniciar la v2 para evitar agotar el límite de tasa de Let's Encrypt al reemitir cinco certificados simultáneamente.

FAQ

¿Debo reescribir todas las reglas de router para Traefik v3?

No. Una regla Host(app.example.com) escrita con backticks es válida en ambas versiones, lo cual cubre la mayoría de las configuraciones de Compose. La reescritura solo es necesaria cuando una regla utiliza funciones exclusivas de v2: regex o placeholders dentro de Path y PathPrefix, varios hostnames dentro de un mismo Host(), comillas en lugar de backticks, o los matchers Headers, HeadersRegexp y HostHeader que fueron eliminados.

¿Qué pasó con ipWhiteList en Traefik v3?

Se renombró a ipAllowList. La configuración interna no cambia, por lo que una etiqueta de v2 como traefik.http.middlewares.office.ipwhitelist.sourcerange=10.0.0.0/24 se convierte en la misma línea pero con ipallowlist. Las versiones actuales de v3, incluida la v3.5, aún aceptan el nombre antiguo como un alias deprecado; por lo tanto, una etiqueta no renombrada seguirá aplicando la allowlist sin avisar. No use esto como excusa para no renombrar: el alias tiene programada su eliminación. Si usa un nombre de middleware que Traefik no reconoce, el sistema fallará con un error de router y un 404. El dashboard mostrará el error y las peticiones a ese hostname devolverán 404.

¿Puede Traefik v3 seguir leyendo la sintaxis de reglas de v2?

Sí. Configure core.defaultRuleSyntax: v2 en la configuración estática para mantener la sintaxis de v2 como predeterminada durante la migración. Use la etiqueta ruleSyntax=v2 por router para los casos individuales después de volver al valor predeterminado. Considere ambas opciones como temporales: Traefik las marcó como deprecadas en v3.4 y las eliminará en la próxima versión mayor.

¿Mis certificados de Let's Encrypt sobrevivirán a 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 solo por cambiar el binario. De todos modos, copie el archivo en un lugar seguro antes de comenzar; un rollback o un volumen eliminado que pierda acme.json forzará la reemisión de todos los certificados a la vez, y Let's Encrypt solo permite cinco certificados duplicados por semana para el mismo conjunto de hostnames.

¿Por qué Traefik v3 falla al iniciar después de la actualización?

Casi siempre ocurre porque la configuración estática aún contiene una opción eliminada en v3, y Traefik no inicia si encuentra opciones que no reconoce. Para los elementos conocidos restantes (pilot, providers.docker.swarmMode, experimental.http3), el log indica incompatible deprecated static option found y nombra al culpable; para cualquier otro elemento desconocido por v3, como tls.caOptional, indicará field not found junto al nodo. Elimine o reemplace cada elemento y reinicie el contenedor.