SSD Nodes Learn Hosting plans →
指南 Matt Connor作者: Matt Connor

Traefik v2 升級 v3 常見錯誤與設定遷移指南

Traefik v3 移除 swarmMode 與 pilot 設定,導致服務無法啟動。本文整理常見的 deprecated configuration 錯誤排除方式,並說明如何逐步遷移路由規則與中介軟體。

Traefik v2 與 v3 有哪些變更

從 Traefik v2 遷移至 v3,主要是重新命名。其中最知名的變更,是將 ipWhiteList middleware 改名為 ipAllowList。除此之外,v3 也收緊 router 規則語法(PathPrefix 不再具備 regex 功能,部分 matchers 已重新命名或移除),並直接移除少數 providers 與選項。其餘設定仍可沿用:entrypoints、ACME 憑證設定、Docker labels 工作流程,以及您的 acme.json 都不受影響。v3 也提供相容模式,可繼續使用 v2 規則語法。因此,您可以先升級 binary,再逐一修改各服務的規則,而不必在同一個晚上一次完成,降低升級風險。

本指南假設您使用 Traefik reverse proxy 指南中的標籤式 Docker Compose 設定。該頁面以 v3 為基礎;本頁適用於仍在執行 traefik:v2 tag 的主機。

重新命名與移除項目

  • ipWhiteList 現已更名為 ipAllowList,適用於 HTTP 與 TCP 中介軟體。內部的選項維持不變,因此 sourcerange 的含義完全相同。目前的 v3 版本(包含 v3.7)仍將舊名稱視為已棄用的別名並強制執行列表,同時會記錄棄用警告,因此這次重新命名不會導致服務中斷。建議仍應進行更名:舊名稱已棄用,且 v2.11 已支援 ipAllowList,因此可在升級前先行完成更名。
  • providers.docker.swarmMode=true 已移除。Swarm 現有專屬的 provider,設定方式為 providers.swarm.endpoint。
  • pilot 區段已完全移除。
  • experimental.http3 已移除。HTTP/3 現直接於 entrypoint 中啟用。
  • tls.caOptional 已從 providers 與 forwardAuth 中介軟體中移除。若該中介軟體位於 自架 Authentik SSO 前端,刪除 caOptional 行即完成遷移,因為 forwardAuth 位址、受信任標頭以及後方的 outpost 在 v3 中的行為皆相同。
  • InfluxDB v1 指標 provider、Rancher provider 與 Marathon provider 已移除。
  • 追蹤功能已遷移至 OpenTelemetry。專屬的追蹤後端(包含 Jaeger 與 Zipkin 整合)已移除,v3 改為輸出 OTLP(OpenTelemetry 協定)。
  • headers 中介軟體內已棄用的 ssl* 選項(sslRedirect、sslHost 及其他)已移除。現由 entrypoint 重新導向與 redirectScheme 中介軟體取代。

這些移除項目的影響比預期更重大,因為若靜態設定檔包含已移除或未知的選項,Traefik 將無法啟動。殘留的 pilot、swarmMode、experimental.http3 或 provider tls.caOptional 設定行會導致容器在開機時停止:Traefik 會先記錄一行指出殘留設定的訊息(例如 Docker provider tls.CAOptional 選項已在 v3 中移除),隨後以 incompatible deprecated install configuration option found 錯誤失敗。v3.4 之前的版本將該訊息顯示為 incompatible deprecated static option found。若選項為 Traefik 無法識別的內容(例如拼字錯誤),則會以 field not found 錯誤停止節點。請在更換映像檔標籤前,先清理靜態設定檔。

若中介軟體名稱為 Traefik 無法識別(拼字錯誤或已被移除而非改名),則會產生不同的失敗結果:參照該中介軟體的路由器將無法建立路由並載入錯誤,儀表板會標記該錯誤,且 API 會回報 middleware "offce@docker" does not exist。對該主機名稱的請求將收到 404 錯誤,因為路由器未成功啟動。請注意,ipwhitelist 在目前的 v3 版本中不屬於此類:它作為已棄用的別名保留,因此未更名的標籤仍可正常運作。

規則語法變更

規則是進行實際重寫的地方。v3 版本中的變更如下:

  • 引號用法並未改變。兩個版本皆接受以反引號或跳脫雙引號包覆的規則值,並拒絕單引號,因此 Host(app.example.com) 以及跳脫雙引號的 Host("app.example.com") 均維持有效。
  • PathPrefix 不再支援正規表示式或 {id} 風格的預留位置。v2 的規則(例如 PathPrefix(/api/{version:v[0-9]+}))必須改為使用 Go 正規表示式語法的 PathRegexp 比對器。
  • 比對器現在僅接受單一值。v2 允許 Host(app.example.com,www.example.com);v3 則要求寫成 Host(app.example.com) || Host(www.example.com)。例外情況為 Header、HeaderRegexp、Query 與 QueryRegexp,這些仍接受名稱加上一個值。
  • Headers 與 HeadersRegexp 已重新命名為 Header 與 HeaderRegexp。
  • HostHeader 已移除。請改用 Host,其在 v3 中具備相同比對功能。
  • 新增了兩個比對器:PathRegexp 與 QueryRegexp。用於在規則內比對客戶端位址的 ClientIP,已存在於 v2.11 並保留不變。

好消息是:使用反引號編寫的簡單 Host(app.example.com) 規則已是有效的 v3 語法。大多數小型 Compose 設定正是如此,這意味著大多數標籤無需修改規則即可遷移。

開始前先稽核標籤

只要執行一次搜尋,就能估算遷移規模,因為每個不相容的標籤變更都會留下可由 grep 找到的模式:

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

每個命中結果都是需要修改的一行。ipwhitelist 變更為 ipallowlist。HostHeader 變更為 Host。Headers 變更為 Header。{...} 佔位符放在 PathPrefix 內時,會變更為 PathRegexp 比對器。Host() 內的逗號會變更為由 || 連接的兩個 Host() 比對器。若沒有命中結果,表示標籤已符合 v3 語法,遷移工作可縮減為靜態設定與映像標籤。若命中結果列滿整個畫面,也正適合重新評估這是否仍是這台主機的正確代理,而 Traefik 與 Nginx 和 Caddy 的比較 會將這項重寫成本,與另外兩者要求你為每個應用程式處理的工作放在一起衡量。

維持不變的部分

Entrypoint 及其 HTTP-to-HTTPS 重新導向、同時支援兩種 challenge type 的 ACME resolver、exposedByDefault、router 與 service label、loadbalancer.server.port,以及 dashboard,在 v3 中都與 v2 相同。憑證也會沿用,因為 v3 會繼續讀取 v2 寫入的 acme.json。不過,開始前仍應先備份該檔案,因為回復時若遺失檔案,就會直接觸發 Let's Encrypt 的重複憑證速率限制:

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

遷移路徑

步驟 1:鎖定當前執行版本。 將所有 traefik:latest 或 traefik:v2 標籤改為您目前使用的確切版本(例如 traefik:v2.11),並將整個 compose 目錄提交至 git。後續每個步驟若有問題,皆可透過 checkout 還原。若您對使用 docker compose up -d <service> 重建單一服務的操作尚未熟練,請參考 Docker Compose 基礎指南,本遷移過程將依賴這些操作。

步驟 2:清理靜態設定並開啟相容模式。 移除 v3 已棄用的所有選項(pilot、swarmMode、tls.caOptional、experimental.http3),接著設定 v3 預設將規則視為 v2 語法。在 traefik.yml 中設定:

core:
  defaultRuleSyntax: v2

或在 compose 的 command: 清單中加入旗標:--core.defaultRuleSyntax=v2。相容模式僅涵蓋規則語法,不會恢復已移除的選項,也不會自動重新命名中間件(middleware)。

步驟 3:在 v2.11 版本下套用中間件重新命名。 在您的 compose 檔案中搜尋舊名稱:grep -rn ipwhitelist docker-compose*.yml。將每個 ipwhitelist 標籤編輯為 ipallowlist,並使用 docker compose up -d 重建這些服務。v2.11 已內建 IPAllowList 中間件,因此在切換版本前,重新命名的標籤即可運作,且 IPWhiteList 的棄用警告將從 v2 日誌中消失。若版本早於 v2.11 則不支援新名稱,因此若您在步驟 1 鎖定了較舊的 v2 版本,請先升級至 traefik:v2.11。若有遺漏,目前的 v3 仍會將舊名稱視為棄用別名(deprecated alias)並予以支援,因此存取控制清單仍會生效;請在後續階段修正,無需在凌晨緊急處理。

步驟 4:切換映像檔標籤。 將 Traefik 映像檔設定為目前的 v3 版本,截至 2026 年 10 月 11 日為 traefik:v3.7(v3.7.14 為最新修補版本),接著執行:

docker compose up -d
docker compose logs -f traefik

由於已開啟相容模式,您的 v2 規則可持續匹配;且因中間件重新命名已在 v2.11 生效,這些路由器將正常啟動。健康的日誌應不包含 field not found 或 does not exist 相關訊息。

請務必評估此步驟可能造成的服務中斷窗口。若路由器參照了 v3 不支援的中間件名稱(如拼字錯誤或已移除的選項),該服務將從新版 Traefik 啟動起失效,直到您修正標籤並重建應用程式容器為止。若路由絕對不能中斷,請在切換前從該路由器的 middlewares 標籤中移除可疑的中間件,待切換後再加回,並預先評估該路由在切換期間是否能暫時失去該功能。

步驟 5:逐一遷移服務規則。 每次處理一個應用程式:將其規則重寫為 v3 語法,僅使用 docker compose up -d app 重建該服務,並在處理下一個服務前進行測試。若某個服務的規則暫時無法重寫,請為該路由器加上逃生艙標籤 traefik.http.routers.app.ruleSyntax=v2,然後繼續進行。

步驟 6:關閉相容模式。 當所有規則皆已改為 v3 語法後,刪除 defaultRuleSyntax 及任何 ruleSyntax 標籤,重新啟動 Traefik,並確認儀表板中所有路由器狀態皆為綠色。請勿長期依賴相容模式:Traefik 已於 v3.4 棄用上述兩項設定,並將於下一個主要版本中移除,它們僅作為過渡橋樑,而非最終目標。

前後對照:單一服務的標籤

以下是一個同時包含所有常見變更的應用程式:多值 Host、PathPrefix 佔位符,以及 ipWhiteList 中介軟體。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

以下是相同服務遷移至 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

有 2 個標籤變更。規則將多值 Host 拆分為 2 個以 || 連接的比對器,並將佔位符替換為 PathRegexp;中介軟體標籤則將 ipwhitelist 替換為 ipallowlist。entrypoint、憑證解析器、路由器與中介軟體的連接,以及服務連接埠都未變更。

使用儀表板測試每項服務

每次切換後,開啟儀表板的 HTTP routers 頁面。每個 router 都應顯示綠色。帶有錯誤徽章的 router 會指出確切問題,通常是新名稱下不存在的 middleware,或是 rule v3 無法剖析。接著從外部逐一確認每個主機名稱:

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

出現 200 或應用程式通常會進行的重新導向,表示路由與 TLS 都正常運作。Traefik 回傳 404,表示 router 未成功啟動;請返回儀表板查看錯誤。作業期間,請在第二個終端機中持續開啟 docker compose logs -f traefik,因為每次容器重新啟動時,所有剖析失敗都會立即記錄在其中。

復原的完整性

請保留 v2 的 compose 檔案、其靜態設定以及 acme.json 備份,直到所有服務皆已切換至 v3 並經過實際驗證。所謂復原是指切換回遷移前的 commit 並執行 docker compose up -d,且必須還原整個檔案,而不僅僅是 image 標籤。這是因為 v3 專用的語法在 v2 環境下會發生錯誤,正如 v2 語法在 v3 環境下無法運作一樣:PathRegexp 比對器無法解析該語法。重新命名的 ipallowlist 標籤在 v2.11 版本中可正常運作,但在任何更舊的 v2 版本中則無法識別。若過程中 acme.json 遺失或損毀,請在啟動 v2 前先還原備份,以免復原作業因同時重新簽發五張憑證而耗盡 Let's Encrypt 的速率限制。

FAQ

我需要為 Traefik v3 重寫所有的路由器規則嗎?

不需要。使用反引號編寫的標準 Host(app.example.com) 規則在兩個版本中皆有效,這涵蓋了大多數的 Compose 設定。只有在規則使用了 v2 專屬功能時才需要重寫:例如 Path 與 PathPrefix 內的正規表示式或佔位符、單一 Host() 內的多個主機名稱,或是已被移除的 Headers、HeadersRegexp 與 HostHeader 比對器。

Traefik v3 中的 ipWhiteList 發生了什麼變化?

它被重新命名為 ipAllowList,內部的設定保持不變,因此像 traefik.http.middlewares.office.ipwhitelist.sourcerange=10.0.0.0/24 這樣的 v2 標籤,只需將名稱改為 ipallowlist 即可。v2.11 已經支援此新名稱,因此您可以在升級前先行更名。目前的 v3 版本(包含 v3.7)仍將舊名稱視為已棄用的別名,因此未更名的標籤仍會強制執行白名單,僅會在日誌中顯示警告。請將此視為緩衝時間,而非跳過更名的理由:已棄用的名稱隨時可能在後續版本中移除,若 Traefik 無法識別中間件名稱,將會導致嚴重的錯誤,產生路由器錯誤並回傳 404。儀表板會顯示該錯誤,且對該主機名稱的請求將會失敗並回傳 404。

Traefik v3 還能讀取 v2 的規則語法嗎?

可以。在靜態設定中設定 core.defaultRuleSyntax: v2,即可在遷移期間將 v2 語法保留為預設值;在切換回預設值後,可針對個別尚未遷移的項目使用 ruleSyntax=v2 標籤。請將兩者皆視為暫時性方案:Traefik 已於 v3.4 將其棄用,並將在下一個主要版本中移除。

我的 Let's Encrypt 憑證在升級後還能使用嗎?

可以。Traefik v3 會繼續讀取 v2 所寫入的 acme.json 檔案,因此憑證不會僅因為二進位檔案變更而重新簽發。無論如何,請在開始前將該檔案備份至安全處,因為若發生回滾或磁碟區刪除導致遺失 acme.json,將會強制一次性重新簽發所有憑證,而 Let's Encrypt 對相同主機名稱組合每週僅允許簽發 5 張重複憑證。

為什麼 Traefik v3 在升級後無法啟動?

這通常是因為靜態設定中仍包含 v3 已移除的選項,Traefik 會拒絕識別並啟動。對於常見的殘留項目(pilot、providers.docker.swarmMode、experimental.http3 以及提供者的 tls.caOptional),日誌會指出問題來源並顯示 incompatible deprecated install configuration option found(v3.4 及更早版本為 incompatible deprecated static option found);對於 v3 從未聽過的項目(例如拼字錯誤),則會顯示 field not found 並標示節點。請刪除或替換這些項目,然後重新啟動容器。