SSD Nodes Learn
Guide Matt ConnorDi Matt Connor · Aggiornato 2026-07-24

Migrazione da Traefik v2 a v3: cosa cambia

Scopri come risolvere l'errore di configurazione statica con swarmMode o pilot. Guida alla migrazione delle rule e al rinominamento dei middleware HTTP.

Cosa cambia tra Traefik v2 e v3

La migrazione da Traefik v2 a v3 consiste principalmente in un rinominamento di componenti. Il cambiamento principale riguarda il middleware ipWhiteList, che diventa ipAllowList. Oltre a questo, la v3 restringe la sintassi delle router rule (PathPrefix perde le funzionalità regex, diversi matcher vengono rinominati o rimossi), elimina alcuni provider e opzioni, ma mantiene invariati tutti gli altri elementi: entrypoints, configurazione dei certificati ACME, workflow delle Docker labels e il vostro acme.json. La v3 include anche una modalità di compatibilità che permette di utilizzare la sintassi delle rule della v2; questo consente di aggiornare prima il binary e riscrivere le rule un servizio alla volta invece di farlo in un'unica sessione rischiosa.

Questa guida assume l'utilizzo della configurazione Docker Compose basata su label descritta in the Traefik reverse proxy guide. Quella pagina è nativa per la v3; questa guida è per sistemi che utilizzano ancora un tag traefik:v2.

Rinombre e rimozioni

  • ipWhiteList è ora ipAllowList, sia per il middleware HTTP che per il middleware TCP. Le opzioni interne rimangono invariate, quindi sourcerange mantiene lo stesso significato. Le attuali versioni v3, inclusa la v3.5, accettano ancora il vecchio nome come alias deprecato e mantengono la lista attiva; pertanto, questo rinome non causa interruzioni del servizio. Procedere comunque al rinome: l'alias è pianificato per la rimozione e verrà rimosso dalla lista di deprecazione senza avvisi espliciti.
  • providers.docker.swarmMode=true è stato rimosso. Swarm utilizza un proprio provider, configurato come providers.swarm.endpoint.
  • La sezione pilot è stata completamente rimossa.
  • experimental.http3 è stato rimosso. HTTP/3 è abilitato direttamente sull'entrypoint.
  • tls.caOptional è stato rimosso dai provider e dal middleware forwardAuth.
  • Sono stati rimossi il provider delle metriche InfluxDB v1, il provider Rancher e il provider Marathon.
  • Il tracing è passato a OpenTelemetry. I backend di tracing dedicati, incluse le integrazioni Jaeger e Zipkin, sono stati rimossi; la v3 esporta invece OTLP (OpenTelemetry protocol).
  • Le opzioni deprecate ssl* all'interno del middleware headers (sslRedirect, sslHost e le altre) sono state rimosse. Le redirezioni dell'entrypoint e il middleware redirectScheme le hanno sostituite.

Queste rimozioni sono critiche perché Traefik non si avvia se la configurazione statica contiene un'opzione sconosciuta. Una riga pilot o swarmMode residua blocca il container all'avvio con un messaggio di errore incompatible deprecated static option found che indica l'opzione; un'opzione mai esistita (un errore di battitura o tls.caOptional) blocca l'avvio con un errore field not found. Pulire la configurazione statica prima di aggiornare il tag dell'immagine.

Un nome di un middleware che Traefik non riconosce (un errore di battitura o un nome rimosso invece che reso alias) genera un errore differente: il router che lo utilizza fallisce il caricamento invece di creare una rotta, la dashboard lo segnala e l'API riporta middleware "offce@docker" does not exist. Le richieste a quell'hostname restituiscono un errore 404 perché il router non è stato avviato. Si noti che ipwhitelist NON appartiene a questa categoria nelle attuali v3: rimane come alias deprecato, quindi un label non rinominato continua a funzionare senza errori.

Cambiamenti nella sintassi delle regole

Le regole permettono la riscrittura effettiva dei dati. Le modifiche nella v3:

  • Sono necessari i backtick per i valori all'interno dei matcher. La v2 accettava anche le virgolette doppie; la v3 no, quindi Host("app.example.com") deve diventare Host(app.example.com).
  • PathPrefix non supporta più le espressioni regolari o i segnaposto in stile {id}. Una regola v2 come PathPrefix(/api/{version:v[0-9]+}) deve diventare un matcher PathRegexp scritto con la sintassi delle espressioni regolari Go.
  • I matcher ora accettano un singolo valore. La v2 permetteva Host(app.example.com,www.example.com); la v3 richiede Host(app.example.com) || Host(www.example.com). Le eccezioni sono Header, HeaderRegexp, Query e QueryRegexp, che richiedono ancora un nome più un valore.
  • Headers e HeadersRegexp sono rinominate in Header e HeaderRegexp.
  • HostHeader è stata rimossa. Utilizzare Host, che nella v3 corrisponde alla stessa funzione.
  • Sono stati introdotti due nuovi matcher: QueryRegexp e ClientIP per il matching dell'indirizzo client all'interno di una regola.

La buona notizia: una regola Host(app.example.com) semplice scritta con i backtick è già una sintassi v3 valida. La maggior parte delle configurazioni Compose ridotte utilizza esattamente questo formato, il che significa che la maggior parte delle label migra senza modifiche alle regole.

Audit i propri label prima di iniziare

È possibile misurare l'entità della migrazione con una singola ricerca. Ogni modifica che rompe i label lascia un pattern rilevabile tramite grep:

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

Ogni corrispondenza indica una riga da modificare. ipwhitelist diventa ipallowlist. HostHeader diventa Host. Headers diventa Header. Un segnaposto {...} all'interno di PathPrefix diventa un matcher PathRegexp. Una virgola all'interno di Host() diventa due matcher Host() uniti da ||. Zero corrispondenze indicano che i label utilizzano già la sintassi v3 valida; in questo caso, la migrazione si limita alla configurazione statica e al tag dell'immagine.

Cosa rimane invariato

Gli entrypoint e il relativo redirect da HTTP a HTTPS, i resolver ACME con entrambi i tipi di challenge, exposedByDefault, le label del router e del servizio, loadbalancer.server.port e la dashboard funzionano in v3 esattamente come in v2. Anche i certificati vengono mantenuti, poiché v3 continua a leggere il file acme.json generato da v2. Effettua comunque un backup del file prima di iniziare: un rollback che causi la perdita del file comporterà il superamento del limite di velocità (rate limit) per i certificati duplicati di Let's Encrypt:

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

Il percorso di migrazione

Step 1: blocca la versione attuale. Sostituisci ogni tag traefik:latest o traefik:v2 con la versione esatta in uso, ad esempio traefik:v2.11, e committa l'intera directory compose su git. Ogni passaggio successivo sarà reversibile tramite un checkout. Se la ricreazione di un singolo service con docker compose up -d <service> non è ancora un'operazione automatica, la guida ai concetti base di Docker Compose spiega le operazioni necessarie per questa migrazione.

Step 2: pulisci la configurazione statica e attiva la modalità compatibilità. Rimuovi ogni opzione eliminata dalla v3 (pilot, swarmMode, tls.caOptional, experimental.http3), quindi istruisci la v3 a trattare le rules come sintassi v2 di default. In traefik.yml:

core:
  defaultRuleSyntax: v2

Oppure come flag nella lista compose command:: --core.defaultRuleSyntax=v2. La modalità compatibilità riguarda solo la sintassi delle rules. Non ripristina le opzioni rimosse e non rinomina i middleware.

Step 3: prepara la rinomina dei middleware. Cerca nei file compose i vecchi nomi: grep -rn ipwhitelist docker-compose*.yml. Modifica ogni label ipwhitelist in ipallowlist, ma non applicare ancora la modifica, poiché il nuovo nome non esiste nella v2. Queste modifiche verranno applicate insieme al passaggio successivo. (Se ne sfugge una, la v3 attuale riconosce ancora il vecchio nome come alias deprecato, quindi la lista rimane valida; correggila nel passaggio successivo invece di farlo alle 2 del mattino.)

Step 4: aggiorna il tag dell'immagine. Imposta l'immagine di Traefik sulla versione v3 attuale, traefik:v3.5 al momento della scrittura, quindi:

docker compose up -d
docker compose logs -f traefik

Poiché la modalità compatibilità è attiva, le rules v2 continueranno a funzionare, e poiché up -d ha ricreato i service i cui middleware labels sono stati rinominati, i router caricheranno correttamente. Un log corretto non presenta la riga field not found né la riga does not exist.

Valuta con attenzione la finestra di downtime di questo passaggio. Un router che fa riferimento a un middleware name sconosciuto dalla v3 (un errore di battitura o un'opzione rimossa) smette di funzionare dal momento in cui parte il nuovo Traefik fino alla ricreazione del container dell'app; su un singolo host, questo richiede i pochi secondi necessari a docker compose up -d per elaborare la lista. Se una route non può subire interruzioni, rimuovi il middleware rinominato dalla label middlewares di quel router prima del passaggio e riaggiungilo dopo; decidi in anticipo se quella route può funzionare senza la sua IP allow list durante l'intervallo.

Step 5: migra le rules un service alla volta. Procedi un'app alla volta: riscrivi la sua rule in sintassi v3, ricrea solo quel service con docker compose up -d app e testalo prima di procedere. Se un service ha una rule che non puoi ancora riscrivere, assegna a quel singolo router la label di emergenza traefik.http.routers.app.ruleSyntax=v2 e continua il lavoro.

Step 6: disattiva la modalità compatibilità. Quando ogni rule è in sintassi v3, elimina defaultRuleSyntax e ogni label ruleSyntax, riavvia Traefik e conferma che ogni router sia ancora verde nella dashboard. Non mantenere la modalità compatibilità attiva: Traefik ha deprecato entrambe le opzioni nella v3.4 e le rimuoverà nella prossima major version; sono un ponte, non una destinazione finale.

Prima e dopo: le label di un servizio

Ecco un'applicazione che presenta contemporaneamente tutte le modifiche principali: un Host multi-valore, un placeholder PathPrefix e un middleware ipWhiteList. Il blocco 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

Lo stesso servizio migrato alla 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

Due label sono cambiate. La regola ha diviso il suo Host multi-valore in due matcher uniti da || e ha sostituito il placeholder con PathRegexp; la label del middleware ha sostituito ipwhitelist con ipallowlist. L'entrypoint, il certificate resolver, il collegamento router-middleware e la porta del servizio non sono cambiati.

Test each service with the dashboard

Dopo ogni flip, apri la pagina HTTP routers della dashboard. Ogni router deve essere verde. Un router con un badge di errore indica il problema specifico; solitamente si tratta di un middleware non esistente con il nuovo nome o di una regola non analizzabile da v3. Successivamente, conferma il funzionamento dall'esterno, un hostname alla volta:

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

Un 200 o il normale redirect della tua app indicano che il routing e il TLS sono corretti. Un 404 da Traefik indica che il router non è partito; torna alla dashboard per leggere l'errore. Mantieni docker compose logs -f traefik aperto in un secondo terminale durante l'operazione, poiché ogni errore di parsing viene registrato lì non appena un container si riavvia.

Integrità del rollback

Conserva il file compose v2, la sua configurazione statica e il backup acme.json finché ogni servizio non è instradato su v3 e non è stato testato operativamente. Il rollback consiste nel fare il checkout del commit precedente alla migrazione ed eseguire docker compose up -d. È necessario utilizzare l'intero file e non solo il tag dell'immagine. I label specifici per v3 sono errati sotto v2, esattamente come i label v2 erano errati sotto v3: ipallowlist non esiste in v2 e un matcher PathRegexp non può essere analizzato in quel contesto. Se acme.json è andato perso o è stato danneggiato durante il processo, ripristina la copia di backup prima di avviare v2. Questo evita di esaurire il limite di rate limit di Let's Encrypt tentando di riemettere cinque certificati contemporaneamente.

FAQ

Devo riscrivere ogni regola del router per Traefik v3?

No. Una regola Host(app.example.com) standard scritta con backtick è valida in entrambe le versioni; questo copre la maggior parte delle configurazioni Compose. La riscrittura è necessaria solo se la regola utilizza funzionalità esclusive della v2: regex o placeholder all'interno di Path e PathPrefix, più hostname all'interno di un singolo Host(), virgolette al posto dei backtick, o i matcher Headers, HeadersRegexp e HostHeader rimossi.

Cosa è successo a ipWhiteList in Traefik v3?

È stata rinominata in ipAllowList. La configurazione interna rimane invariata, quindi un label v2 come traefik.http.middlewares.office.ipwhitelist.sourcerange=10.0.0.0/24 diventa la stessa riga con ipallowlist. Le versioni attuali della v3, inclusa la v3.5, accettano ancora il vecchio nome come alias deprecato; pertanto, un label non rinominato continua a gestire la allowlist senza errori. Considerate questa compatibilità come temporanea: l'alias verrà rimosso. Se viene utilizzato un nome di middleware che Traefik non riconosce, il sistema restituirà un errore del router e un errore 404. La dashboard mostrerà l'errore e le richieste a quell'hostname restituiranno 404.

Traefik v3 può ancora leggere la sintassi delle regole v2?

Sì. Impostate core.defaultRuleSyntax: v2 nella configurazione statica per mantenere la sintassi v2 come default durante la migrazione. Utilizzate il label ruleSyntax=v2 per singolo router per i casi residui dopo aver ripristinato il default. Considerate entrambe le opzioni come temporanee: Traefik le ha deprecate nella v3.4 e le rimuoverà nella prossima versione major.

I miei certificati Let's Encrypt sopravviveranno all'aggiornamento?

Sì. Traefik v3 continua a leggere il file acme.json generato dalla v2; i certificati non vengono riemessi solo a causa del cambio di binario. Copiate comunque il file in un luogo sicuro prima di iniziare: un rollback o un volume eliminato che causa la perdita di acme.json costringe al riemissione di tutti i certificati contemporaneamente. Let's Encrypt permette solo cinque certificati duplicati a settimana per lo stesso set di hostname.

Perché Traefik v3 non si avvia dopo l'aggiornamento?

Quasi sempre perché la configurazione statica contiene ancora un'opzione rimossa dalla v3. Traefik non si avvia se incontra opzioni non riconosciute. Per i residui noti (pilot, providers.docker.swarmMode, experimental.http3), il log riporta incompatible deprecated static option found indicando il colpevole; per opzioni mai gestite da v3, come tls.caOptional, il log riporta field not found con il nodo specifico. Eliminate o sostituite ogni opzione, quindi riavviate il container.