Mal wieder Tech-Talk. Zur Verteilung des Web-Traffics auf verschiedene Anwendungen nutze ich seit einiger Zeit Traefik. Den beliebten Router gibt es nun (als beta-Version) in der Version v2.0, in der konzeptionell einiges geändert wurde, was leider einen schnellen Umstieg verhindert.

Auch die Doku ist noch nicht vollständig, so dass der Umbau länger dauerte als erwartet.

Hier nun einige Änderungen, die bei einem Docker-Setup notwendig sind.

Kommandozeilenparameter

Schon hier sieht man, dass kein Stein auf dem anderen geblieben ist:

v1.7

      - "--acme"
      - "--acme.acmelogging=true"
      - "--acme.email=${ACME_EMAIL}"
      - "--acme.entryPoint=https"
      - "--acme.httpchallenge"
      - "--acme.httpchallenge.entrypoint=http"
      - "--acme.onhostrule=true"
      - "--acme.storage=/etc/traefik/acme/acme.json"
      - "--defaultEntryPoints=https,http"
      - "--docker"
      - "--docker.domain=${DOMAINNAME}"
      - "--docker.endpoint=unix:///var/run/docker.sock"
      - "--docker.network=traefik_proxy"
      - "--docker.watch=true"
      - "--entrypoints=Name:http Address::80 Redirect.EntryPoint:https"
      - "--entrypoints=Name:https Address::443 TLS"
      - "--entrypoints=Name:traefik Address::8080"
      - "--logLevel=INFO"

v2.0

      - "--providers.docker=true"
      - "--providers.docker.network=traefik_proxy"
      - "--entryPoints.http.address=:80"
      - "--entryPoints.https.address=:443"
      - "--certificatesResolvers.k13.acme.email=${ACME_EMAIL}"
      - "--certificatesResolvers.k13.acme.storage=acme.json"
      - "--certificatesResolvers.k13.acme.httpChallenge.entryPoint=http"
      - "--certificatesResolvers.k13.acme.httpChallenge=true"

Auch die acme.json liegt nun nicht mehr in /etc/traefik/acme/ sondern direkt in /.

Container Labels

Ein simples Beispiel

v1.7

      - "traefik.frontend.rule=Host:mm.${DOMAINNAME}"  

v2.0

      - "traefik.http.routers.mm.rule=Host(`mm.${DOMAINNAME}`)"
      - "traefik.http.routers.mm.tls.certresolver=k13"
      - "traefik.http.middlewares.mm.redirectscheme.scheme=https"    

Unschön finde ich, dass man nun mehr Labels vergeben muss als vorher. Neben der rule muss bei v2.0 bei jedem Container auch der certresolver und das redirectscheme angegeben werden. Bei v1.7 konnte man das redirect am Entrypoint festlegen (also einmal für alle Container).

Mit www-redirect

v1.7

      - "traefik.frontend.rule=Host:${DOMAINNAME},www.${DOMAINNAME}"
      # redirect www to non-www
      - "traefik.frontend.redirect.regex=^https?://www.${DOMAINNAME}/(.*)"
      - "traefik.frontend.redirect.replacement=https://${DOMAINNAME}/$${1}"
      - "traefik.frontend.redirect.permanent=true"

v2.0

      # ohne www
      - "traefik.http.routers.ghost.rule=Host(`${DOMAINNAME}`)"
      - "traefik.http.routers.ghost.tls.certresolver=k13"
      - "traefik.http.middlewares.ghost.redirectscheme.scheme=https"    
      # mit www
      - "traefik.http.routers.ghostwww.rule=Host(`www.${DOMAINNAME}`)"
      - "traefik.http.routers.ghostwww.tls.certresolver=k13"
      - "traefik.http.middlewares.ghostwww.redirectscheme.scheme=https"    
      # redirect www to non-www
      - "traefik.http.middlewares.www-redirect.redirectregex.regex=^https://www.${DOMAINNAME}/(.*)"
      - "traefik.http.middlewares.www-redirect.redirectregex.replacement=https://${DOMAINNAME}/$${1}"
      - "traefik.http.middlewares.www-redirect.redirectregex.permanent=true"
      - "traefik.http.routers.ghostwww.middlewares=www-redirect"

Auch hier ist das v2.0 Setup wieder komplexer. Man muss für beide Hosts (mit/ohne www) eigene Rules anlegen (ghost und ghostwww). Eine kommaseparierte Aufzählung wie in v1.7 funktioniert nicht.

Für das Redirect legt man eine Middleware an, die dann dem Router ghostwww nochmals explizit zugewiesen werden muss.

Mit PathPrefix[Strip]

v1.7

      - "traefik.cookie.frontend.rule=Host:${DOMAINNAME}; PathPrefixStrip: /cookie"
      - "traefik.gpx.frontend.rule=Host:${DOMAINNAME}; PathPrefixStrip: /Gpx"

v2.0

      - "traefik.http.routers.nginx.rule=Host(`${DOMAINNAME}`) && (PathPrefix(`/cookie/`) || PathPrefix(`/Gpx/`))"
      - "traefik.http.routers.nginx.tls.certresolver=k13"
      - "traefik.http.middlewares.nginx-stripprefix.stripprefix.prefixes=/cookie, /Gpx"
      - "traefik.http.routers.nginx.middlewares=nginx-stripprefix"
      - "traefik.http.middlewares.nginx.redirectscheme.scheme=https"    

Aus den 2 Frontend-Rules bei v1.7 wird eine Router-Rule in v2.0. Will man das zusätzlich "strippen", so muss wieder eine Middleware erzeugt und zugewiesen werden.

Ein weiteres Problem war, dass bei der rule die Parameter von PathPrefix mit abschliessendem / angegeben werden müssen, ohne habe ich es nicht zum Laufen gebracht.