SSD Nodes Learn Hosting plans →
Przewodniki Matt ConnorAutor: Matt Connor · Zaktualizowano 2026-08-28

Migracja Traefik v2 do v3: co przestaje działać

Traefik v3 nie uruchomi się, jeśli w konfiguracji statycznej występuje swarmMode lub pilot. Sprawdź jak naprawić błąd incompatible deprecated static option i zmigrować reguły.

Co zmienia się między Traefik v2 a v3

Migracja z Traefik v2 do v3 polega głównie na zmianie nazw; najbardziej znaną jest zmiana middleware ipWhiteList na ipAllowList. Poza tym v3 zaostrza składnię reguł routera (PathPrefix traci funkcje regex, kilka matcherów zostało przemianowanych lub usuniętych), całkowicie usuwa niektóre providery i opcje, a reszta pozostaje bez zmian: entrypoints, konfiguracja certyfikatów ACME, workflow etykiet Docker oraz Twoje acme.json działają nadal. Wersja v3 zawiera również tryb kompatybilności, który utrzymuje działanie składni reguł z v2, dzięki czemu można najpierw zaktualizować plik binarny, a następnie przepisywać reguły dla każdej usługi pojedynczo, zamiast ryzykować wszystko jednego wieczoru.

Ten przewodnik zakłada konfigurację Docker Compose opartą na etykietach z przewodnika po reverse proxy Traefik. Ta strona jest natywna dla v3; niniejszy tekst dotyczy serwera, który nadal używa tagu traefik:v2.

Zmiany nazw i usunięcia

  • ipWhiteList to teraz ipAllowList, zarówno dla middleware HTTP, jak i TCP. Opcje wewnątrz pozostają bez zmian, więc sourcerange zachowuje swoje dokładne znaczenie. Bieżące wydania v3, w tym v3.5, nadal akceptują starą nazwę jako przestarzały alias i wymuszają stosowanie listy, więc ta zmiana nazwy nie powoduje awarii. Należy jednak dokonać zmiany: alias jest przeznaczony do usunięcia i zniknie z listy przestarzałych elementów bez ostrzeżenia.
  • providers.docker.swarmMode=true zostało usunięte. Swarm posiada własnego dostawcę, konfigurowanego jako providers.swarm.endpoint.
  • Sekcja pilot została całkowicie usunięta.
  • experimental.http3 zostało usunięte. HTTP/3 włącza się bezpośrednio w punkcie wejścia (entrypoint).
  • tls.caOptional zostało usunięte z dostawców oraz z middleware forwardAuth. Jeśli ten middleware obsługuje własną instancję Authentik SSO, usunięcie linii caOptional stanowi całą migrację, ponieważ adres forwardAuth, zaufane nagłówki oraz stojący za nimi outpost działają w v3 identycznie.
  • Dostawca metryk InfluxDB v1, dostawca Rancher oraz dostawca Marathon zostały usunięte.
  • Śledzenie (tracing) przeniesiono do OpenTelemetry. Dedykowane backendy śledzenia, w tym integracje Jaeger i Zipkin, zostały usunięte; v3 eksportuje teraz dane za pomocą OTLP (protokół OpenTelemetry).
  • Przestarzałe opcje ssl* wewnątrz middleware headers (sslRedirect, sslHost i pozostałe) zostały usunięte. Zastąpiono je przekierowaniami na poziomie entrypoint oraz middleware redirectScheme.

Te usunięcia mają większe znaczenie, niż się wydaje, ponieważ Traefik odmawia uruchomienia, gdy jego konfiguracja statyczna zawiera nieznaną opcję. Pozostała linia pilot lub swarmMode zatrzymuje kontener podczas startu z komunikatem incompatible deprecated static option found, wskazującym na zbędny element; opcja, której Traefik w ogóle nie rozpoznaje (literówka lub tls.caOptional), zatrzymuje go z komunikatem field not found. Należy oczyścić konfigurację statyczną przed zmianą tagu obrazu.

Nazwa middleware, której Traefik nie rozpoznaje (literówka lub nazwa usunięta, a nie zastąpiona aliasem), powoduje inny błąd: router, który się do niej odwołuje, ładuje się z błędem zamiast trasy, dashboard oznacza go, a API zgłasza middleware "offce@docker" does not exist. Żądania do tej nazwy hosta otrzymują błąd 404, ponieważ router nie został uruchomiony. Należy zauważyć, że ipwhitelist NIE znajduje się w tej kategorii w bieżącej wersji v3: przetrwało jako przestarzały alias, więc nieprzemianowana etykieta nadal działa bez zakłóceń.

Zmiana składni reguł

Reguły to miejsce, w którym odbywa się właściwe przepisywanie ruchu. Zmiany w wersji v3:

  • Wartości wewnątrz dopasowywaczy (matchers) wymagają użycia odwrotnych apostrofów (backticks). Wersja v2 akceptowała również cudzysłowy; v3 ich nie obsługuje, więc Host("app.example.com") musi zostać zmienione na Host(app.example.com).
  • PathPrefix nie obsługuje już wyrażeń regularnych ani symboli zastępczych w stylu {id}. Reguła z v2, taka jak PathPrefix(/api/{version:v[0-9]+}), musi zostać zmieniona na dopasowywacz PathRegexp, zapisany zgodnie ze składnią wyrażeń regularnych języka Go.
  • Dopasowywacze przyjmują teraz tylko jedną wartość. Wersja v2 pozwalała na Host(app.example.com,www.example.com); v3 wymaga zapisu Host(app.example.com) || Host(www.example.com). Wyjątkami są Header, HeaderRegexp, Query oraz QueryRegexp, które nadal przyjmują nazwę oraz wartość.
  • Headers oraz HeadersRegexp zostały przemianowane na Header oraz HeaderRegexp.
  • HostHeader zostało usunięte. Należy użyć Host, które w v3 odpowiada za to samo dopasowanie.
  • Wprowadzono dwa nowe dopasowywacze: QueryRegexp oraz ClientIP, służący do dopasowywania adresu klienta wewnątrz reguły.

Dobra wiadomość: prosta reguła Host(app.example.com) zapisana z użyciem odwrotnych apostrofów jest już poprawną składnią v3. Większość małych konfiguracji Compose korzysta właśnie z tego rozwiązania, co oznacza, że większość etykiet migruje bez konieczności edycji reguł.

Audyt etykiet przed rozpoczęciem

Można oszacować skalę migracji za pomocą jednego wyszukiwania, ponieważ każda zmiana etykiety powodująca błędy pozostawia wzorzec, który można wykryć za pomocą grep:

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

Każde trafienie to jedna linia do edycji. ipwhitelist zmienia się w ipallowlist. HostHeader zmienia się w Host. Headers zmienia się w Header. Symbol zastępczy {...} wewnątrz PathPrefix staje się dopasowaniem PathRegexp. Przecinek wewnątrz Host() staje się dwoma dopasowaniami Host() połączonymi za pomocą ||. Brak trafień oznacza, że etykiety są już zgodne ze składnią v3, a migracja ogranicza się do konfiguracji statycznej oraz tagu obrazu. Ekran pełen trafień to również dobry moment na rozważenie, czy jest to nadal właściwy serwer proxy dla danej maszyny, a porównanie Traefik z Nginx i Caddy pozwala zestawić koszt przepisania konfiguracji z wymaganiami pozostałych dwóch rozwiązań dla każdej aplikacji.

Co pozostaje bez zmian

Punkty wejścia (entrypoints) wraz z przekierowaniem z HTTP na HTTPS, resolvery ACME obsługujące oba typy wyzwań, exposedByDefault, etykiety routerów i usług, loadbalancer.server.port, oraz pulpit nawigacyjny (dashboard) działają w wersji v3 tak samo jak w v2. Certyfikaty również zostają zachowane, ponieważ v3 odczytuje plik acme.json zapisany przez v2. Przed rozpoczęciem prac należy wykonać kopię zapasową tego pliku, ponieważ wycofanie zmian (rollback) prowadzące do jego utraty skutkuje przekroczeniem limitu częstotliwości wydawania certyfikatów przez Let's Encrypt:

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

Ścieżka migracji

Krok 1: przypnij aktualnie używaną wersję. Zmień każdy tag traefik:latest lub traefik:v2 na konkretną wersję, na której pracujesz, na przykład traefik:v2.11, a następnie zatwierdź cały katalog compose w git. Każdy kolejny krok stanie się odwracalny za pomocą checkout. Jeśli odtwarzanie pojedynczej usługi za pomocą docker compose up -d <service> nie jest jeszcze nawykiem, przewodnik po podstawach Docker Compose omawia operacje, na których opiera się ta migracja.

Krok 2: wyczyść konfigurację statyczną i włącz tryb kompatybilności. Usuń każdą opcję porzuconą w wersji v3 (pilot, swarmMode, tls.caOptional, experimental.http3), a następnie poinstruuj v3, aby domyślnie traktowała reguły jako składnię v2. W pliku traefik.yml:

core:
  defaultRuleSyntax: v2

Lub jako flagę na liście command: w compose: --core.defaultRuleSyntax=v2. Tryb kompatybilności obejmuje tylko składnię reguł. Nie przywraca usuniętych opcji i nie zmienia automatycznie nazw middleware.

Krok 3: przygotuj zmianę nazw middleware. Przeszukaj pliki compose pod kątem starych nazw: grep -rn ipwhitelist docker-compose*.yml. Edytuj każdą etykietę ipwhitelist na ipallowlist, ale nie stosuj jeszcze zmian, ponieważ nowa nazwa nie istnieje w v2. Te edycje są wdrażane razem z przełączeniem w następnym kroku. (Jeśli coś zostanie pominięte, obecna wersja v3 nadal honoruje starą nazwę jako przestarzały alias, więc lista nadal egzekwuje reguły; popraw to w kolejnym podejściu, zamiast w środku nocy).

Krok 4: zmień tag obrazu. Ustaw obraz Traefik na aktualną wersję v3, traefik:v3.5 w momencie pisania tego tekstu, a następnie:

docker compose up -d
docker compose logs -f traefik

Ponieważ tryb kompatybilności jest włączony, reguły v2 nadal pasują, a ponieważ up -d również odtworzył usługi, których etykiety middleware zostały zmienione, te routery uruchamiają się poprawnie. Poprawny dziennik nie zawiera linii field not found ani does not exist.

Oceń realnie okno serwisowe, które otwiera ten krok. Router odwołujący się do nazwy middleware, której v3 nie rozpoznaje (literówka lub usunięta opcja), nie działa od momentu uruchomienia nowego Traefik do czasu odtworzenia kontenera aplikacji, co na jednej maszynie zajmuje kilka sekund potrzebnych docker compose up -d na przetworzenie listy. Jeśli trasa absolutnie nie może przestać działać, usuń zmienioną nazwę middleware z etykiety middlewares routera przed przełączeniem i dodaj ją ponownie po nim. Zdecyduj wcześniej, czy trasa może funkcjonować bez listy dozwolonych adresów IP przez minutę przerwy.

Krok 5: migruj reguły usługa po usłudze. Pracuj nad jedną aplikacją naraz: przepisz jej regułę na składnię v3, odtwórz tylko tę usługę za pomocą docker compose up -d app i przetestuj ją przed przejściem dalej. Jeśli jedna usługa posiada regułę, której jeszcze nie możesz przepisać, nadaj temu konkretnemu routerowi etykietę obejścia traefik.http.routers.app.ruleSyntax=v2 i kontynuuj.

Krok 6: wyłącz tryb kompatybilności. Gdy każda reguła będzie miała składnię v3, usuń defaultRuleSyntax oraz wszelkie etykiety ruleSyntax, zrestartuj Traefik i potwierdź, że każdy router nadal jest widoczny jako aktywny w panelu sterowania. Nie pozostawaj w trybie kompatybilności: Traefik uznał obie opcje za przestarzałe w wersji v3.4 i usunie je w kolejnej głównej wersji, więc są one jedynie pomostem, a nie docelowym rozwiązaniem.

Przed i po: etykiety jednej usługi

Oto aplikacja zawierająca wszystkie istotne zmiany jednocześnie: wielowartościowy Host, symbol zastępczy PathPrefix oraz middleware ipWhiteList. Blok 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

Oraz ta sama usługa po migracji do 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

Zmieniono dwie etykiety. Reguła rozdzieliła wielowartościowy Host na dwa dopasowania połączone za pomocą || i zamieniła symbol zastępczy na PathRegexp, a etykieta middleware zamieniła ipwhitelist na ipallowlist. Punkt wejścia (entrypoint), resolver certyfikatów, powiązanie routera z middleware oraz port usługi pozostały bez zmian.

Testowanie każdej usługi za pomocą panelu sterowania

Po każdej zmianie należy otworzyć stronę routerów HTTP w panelu sterowania. Każdy router powinien być oznaczony kolorem zielonym. Router z ikoną błędu wskazuje konkretny problem, zazwyczaj jest to middleware, który nie istnieje pod nową nazwą lub reguła, której v3 nie potrafi przetworzyć. Następnie należy potwierdzić działanie z zewnątrz, sprawdzając każdą nazwę hosta z osobna:

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

Kod 200 lub standardowe przekierowanie aplikacji oznacza, że routing oraz TLS działają poprawnie. Kod 404 zwrócony przez Traefik oznacza, że router nie został uruchomiony; należy wrócić do panelu sterowania i odczytać treść błędu. W trakcie pracy warto mieć otwarte docker compose logs -f traefik w drugim terminalu, ponieważ każdy błąd parsowania pojawia się tam w momencie restartu kontenera.

Weryfikacja wycofywania zmian

Należy zachować plik compose w wersji v2, jego statyczną konfigurację oraz kopię zapasową acme.json, dopóki każda usługa nie będzie kierować ruchu w wersji v3 i nie zostanie przetestowana w warunkach rzeczywistych. Wycofanie zmian oznacza powrót do commita sprzed migracji i uruchomienie docker compose up -d. Operacja ta musi obejmować cały plik, a nie tylko tag obrazu, ponieważ etykiety przeznaczone wyłącznie dla wersji v3 są nieprawidłowe w wersji v2 w taki sam sposób, w jaki etykiety v2 były nieprawidłowe w wersji v3: ipallowlist nie istnieje w wersji v2, a dopasowanie PathRegexp również nie zostanie tam poprawnie zinterpretowane. Jeśli w trakcie procesu plik acme.json został utracony lub uszkodzony, należy przywrócić kopię zapasową przed uruchomieniem wersji v2. Zapobiegnie to wyczerpaniu limitu zapytań Let's Encrypt podczas ponownego wystawiania pięciu certyfikatów jednocześnie.

FAQ

Czy muszę przepisywać każdą regułę routera dla Traefik v3?

Nie. Zwykła reguła Host(app.example.com) zapisana w odwrotnych apostrofach jest poprawna w obu wersjach, co obejmuje większość konfiguracji Compose. Przepisanie jest wymagane tylko wtedy, gdy reguła korzystała z funkcji dostępnych wyłącznie w v2: wyrażeń regularnych lub symboli zastępczych wewnątrz Path i PathPrefix, kilku nazw hostów wewnątrz jednego Host(), cudzysłowów zamiast odwrotnych apostrofów lub usuniętych matcherów Headers, HeadersRegexp i HostHeader.

Co stało się z ipWhiteList w Traefik v3?

Zostało przemianowane na ipAllowList, przy czym konfiguracja wewnątrz pozostała bez zmian, więc etykieta z v2, taka jak traefik.http.middlewares.office.ipwhitelist.sourcerange=10.0.0.0/24, staje się tą samą linią z ipallowlist w środku. Bieżące wydania v3, w tym v3.5, nadal akceptują starą nazwę jako przestarzały alias, więc nieprzemianowana etykieta nadal po cichu egzekwuje listę dozwolonych adresów. Należy traktować to jako rozwiązanie tymczasowe, a nie powód do pominięcia zmiany nazwy: alias jest przeznaczony do usunięcia, a nazwa middleware, której Traefik faktycznie nie rozpoznaje, powoduje błąd routera i kod 404. Panel sterowania wyświetla błąd, a żądania do tego hosta zwracają 404.

Czy Traefik v3 nadal może odczytywać składnię reguł v2?

Tak. Ustaw core.defaultRuleSyntax: v2 w konfiguracji statycznej, aby zachować składnię v2 jako domyślną podczas migracji, a następnie użyj etykiety ruleSyntax=v2 dla poszczególnych routerów po przywróceniu domyślnych ustawień. Traktuj oba rozwiązania jako tymczasowe: Traefik oznaczył je jako przestarzałe w v3.4 i usunie je w kolejnej głównej wersji.

Czy moje certyfikaty Let's Encrypt przetrwają aktualizację?

Tak. Traefik v3 nadal odczytuje plik acme.json zapisany przez v2, więc certyfikaty nie są ponownie wystawiane tylko z powodu zmiany pliku binarnego. Przed rozpoczęciem prac skopiuj plik w bezpieczne miejsce, ponieważ wycofanie zmian lub usunięcie wolumenu, w którym znajduje się acme.json, wymusi jednoczesne ponowne wystawienie wszystkich certyfikatów, a Let's Encrypt pozwala tylko na pięć duplikatów certyfikatów tygodniowo dla tego samego zestawu nazw hostów.

Dlaczego Traefik v3 nie uruchamia się po aktualizacji?

Prawie zawsze dlatego, że konfiguracja statyczna nadal zawiera opcję usuniętą w v3, a Traefik odmawia uruchomienia w przypadku nierozpoznanych opcji. W przypadku znanych pozostałości (pilot, providers.docker.swarmMode, experimental.http3) dziennik wyświetla incompatible deprecated static option found i wskazuje przyczynę; dla wszystkiego, czego v3 nigdy nie obsługiwał, takiego jak tls.caOptional, wyświetla field not found wraz z węzłem. Usuń lub zastąp każdą z nich, a następnie uruchom kontener ponownie.