Traefik — Cloud-native Reverse Proxy mit Service-Discovery

Praxis-Guide zu Traefik v3 — Reverse Proxy und Load Balancer mit automatischer Service-Discovery, Middlewares und TLS via Let's Encrypt für Docker und Co.

Traefik ist ein moderner, Cloud-native Reverse Proxy und Load Balancer, der sich selbst um die Verdrahtung deiner Dienste kümmert. Sein Kniff ist die automatische Service-Discovery: Über Provider für Docker, Kubernetes oder File-Konfiguration liest Traefik laufend aus, welche Container und Backends existieren, und baut daraus zur Laufzeit seine Router und Services – ganz ohne Reload. Genauso komfortabel ist das automatische TLS: Mit einem Certificate-Resolver holt und erneuert Traefik Let's-Encrypt-Zertifikate von selbst. Dieser Guide führt dich von der statischen Grundkonfiguration über Docker-Labels und Middlewares bis zu den Router-Regeln, mit denen du den Datenverkehr feingranular steuerst.

CLI & statische Konfiguration

traefik --configFile=<path> — Startet Traefik mit einer bestimmten Konfigurationsdatei.

traefik --configFile=/etc/traefik/traefik.yml

traefik version — Zeigt die Traefik-Version an.

traefik version

traefik healthcheck — Führt einen Health-Check gegen eine laufende Traefik-Instanz aus.

traefik healthcheck --ping

entryPoints: — Definiert die EntryPoints für HTTP- und HTTPS-Verkehr (traefik.yml).

entryPoints:
  web:
    address: ":80"
  websecure:
    address: ":443"

api: — Aktiviert das Traefik-Dashboard. insecure: true öffnet es ungeschützt und gehört nur in die Entwicklung – in Produktion das Dashboard per Router und Middleware absichern.

api:
  dashboard: true
  insecure: true  # Access at http://localhost:8080

providers.docker: — Aktiviert den Docker-Provider zur automatischen Erkennung von Containern. Der gemountete Docker-Socket gewährt Root-äquivalenten Zugriff – daher nur lesend (:ro) einbinden und den Zugriff strikt begrenzen.

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false

providers.file: — Aktiviert die dateibasierte dynamische Konfiguration mit automatischem Reload.

providers:
  file:
    directory: /etc/traefik/dynamic/
    watch: true

Docker-Labels — Routing

traefik.enable=true — Aktiviert Traefik für diesen Container (wenn exposedByDefault auf false steht).

labels:
  - traefik.enable=true

traefik.http.routers.<name>.rule=Host(`<domain>`) — Routet den Verkehr anhand des Hostnamens.

labels:
  - traefik.http.routers.myapp.rule=Host(`app.example.com`)

traefik.http.routers.<name>.rule=Host(`<domain>`) && PathPrefix(`<path>`) — Routet anhand von Hostname und URL-Pfad-Präfix.

labels:
  - traefik.http.routers.api.rule=Host(`example.com`) && PathPrefix(`/api`)

traefik.http.routers.<name>.entrypoints=<entry> — Legt fest, auf welchen EntryPoints der Router lauscht.

labels:
  - traefik.http.routers.myapp.entrypoints=websecure

traefik.http.services.<name>.loadbalancer.server.port=<port> — Setzt den Port des Backend-Service im Container.

labels:
  - traefik.http.services.myapp.loadbalancer.server.port=8080

traefik.http.routers.<name>.priority=<n> — Setzt die Router-Priorität (höhere Zahl = höhere Priorität).

labels:
  - traefik.http.routers.specific.priority=100

Docker-Labels — TLS & Let's Encrypt

traefik.http.routers.<name>.tls=true — Aktiviert TLS für einen Router.

labels:
  - traefik.http.routers.myapp.tls=true

traefik.http.routers.<name>.tls.certresolver=<resolver> — Nutzt einen Certificate-Resolver (Let's Encrypt) für automatisches TLS.

labels:
  - traefik.http.routers.myapp.tls.certresolver=letsencrypt

certificatesResolvers (HTTP-01): — Konfiguriert Let's Encrypt mit der HTTP-01-Challenge (traefik.yml).

certificatesResolvers:
  letsencrypt:
    acme:
      email: admin@example.com
      storage: /etc/traefik/acme.json
      httpChallenge:
        entryPoint: web

certificatesResolvers (DNS-01): — Nutzt die DNS-01-Challenge für Wildcard-Zertifikate.

certificatesResolvers:
  letsencrypt:
    acme:
      email: admin@example.com
      storage: /etc/traefik/acme.json
      dnsChallenge:
        provider: cloudflare

traefik.http.routers.<name>.tls.domains[0].main=<domain> — Setzt die Hauptdomain für das TLS-Zertifikat.

labels:
  - traefik.http.routers.myapp.tls.domains[0].main=example.com
  - traefik.http.routers.myapp.tls.domains[0].sans=*.example.com

Docker-Labels — Middleware

traefik.http.routers.<name>.middlewares=<middleware> — Hängt eine Middleware an einen Router.

labels:
  - traefik.http.routers.myapp.middlewares=redirect-https

traefik.http.middlewares.<name>.redirectscheme.scheme=https — Leitet HTTP auf HTTPS um.

labels:
  - traefik.http.middlewares.redirect-https.redirectscheme.scheme=https
  - traefik.http.middlewares.redirect-https.redirectscheme.permanent=true

traefik.http.middlewares.<name>.basicauth.users=<user:hash> — Fügt HTTP-Basic-Authentifizierung hinzu.

labels:
  - traefik.http.middlewares.auth.basicauth.users=admin:$$apr1$$hash

traefik.http.middlewares.<name>.headers.sslRedirect=true — Erzwingt den SSL-Redirect über die Headers-Middleware.

labels:
  - traefik.http.middlewares.security.headers.sslRedirect=true

traefik.http.middlewares.<name>.stripprefix.prefixes=<path> — Entfernt ein Pfad-Präfix, bevor an das Backend weitergeleitet wird.

labels:
  - traefik.http.middlewares.strip-api.stripprefix.prefixes=/api

traefik.http.middlewares.<name>.ratelimit.average=<n> — Rate-Limiting: erlaubt im Mittel n Requests pro Sekunde.

labels:
  - traefik.http.middlewares.ratelimit.ratelimit.average=100
  - traefik.http.middlewares.ratelimit.ratelimit.burst=50

traefik.http.middlewares.<name>.compress=true — Aktiviert gzip-Komprimierung für Antworten.

labels:
  - traefik.http.middlewares.gzip.compress=true

traefik.http.middlewares.<name>.ipallowlist.sourcerange=<cidr> — Beschränkt den Zugriff auf bestimmte IP-Bereiche.

labels:
  - traefik.http.middlewares.internal.ipallowlist.sourcerange=10.0.0.0/8,172.16.0.0/12

Docker Compose — Vollständiges Beispiel

services: (Compose) — Grundlegender Traefik-Service in Docker Compose. Der Docker-Socket wird nur lesend (:ro) gemountet – Zugriff darauf ist Root-äquivalent.

services:
  traefik:
    image: traefik:v3.3
    command:
      - --providers.docker=true
      - --entrypoints.web.address=:80
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro

services: (App-Labels) — Anwendungs-Service mit Traefik-Labels für die automatische Discovery.

services:
  app:
    image: myapp:latest
    labels:
      - traefik.enable=true
      - traefik.http.routers.app.rule=Host(`app.example.com`)
      - traefik.http.routers.app.tls.certresolver=letsencrypt

networks: — Nutzt ein gemeinsames externes Netzwerk, damit Traefik Dienste aus anderen Compose-Dateien erreicht.

# Create first: docker network create traefik-net
networks:
  default:
    name: traefik-net
    external: true

Dateibasierte dynamische Konfiguration

http.routers: — Definiert einen Router in einer dynamischen YAML-Konfigurationsdatei.

# /etc/traefik/dynamic/myapp.yml
http:
  routers:
    myapp:
      rule: "Host(`example.com`)"
      service: myapp
      tls:
        certResolver: letsencrypt

http.services: — Definiert einen Service, der auf ein Backend-Server-Ziel zeigt.

http:
  services:
    myapp:
      loadBalancer:
        servers:
          - url: "http://10.0.0.1:8080"
          - url: "http://10.0.0.2:8080"

tls.certificates: — Lädt eigene TLS-Zertifikate aus Dateien.

tls:
  certificates:
    - certFile: /etc/traefik/certs/example.com.pem
      keyFile: /etc/traefik/certs/example.com-key.pem

Logging & Debugging

log: — Setzt den Log-Level (DEBUG, INFO, WARN, ERROR).

log:
  level: INFO
  filePath: /var/log/traefik/traefik.log

accessLog: {} — Aktiviert das Access-Logging für alle Requests.

accessLog:
  filePath: /var/log/traefik/access.log
  format: json

ping: {} — Aktiviert den /ping-Health-Endpunkt.

ping:
  entryPoint: web

metrics: — Aktiviert den Prometheus-Metrics-Endpunkt.

metrics:
  prometheus:
    entryPoint: metrics
    addEntryPointsLabels: true
    addServicesLabels: true

Nützliche Router-Regeln

Host(`<domain>`) — Matcht Requests anhand des Hostnamens.

Host(`example.com`)

Host(`<domain>`) || Host(`<domain2>`) — Matcht mehrere Hostnamen.

Host(`example.com`) || Host(`www.example.com`)

PathPrefix(`<path>`) — Matcht Requests anhand des URL-Pfad-Präfixes.

PathPrefix(`/api`)

Path(`<path>`) — Matcht einen exakten URL-Pfad.

Path(`/health`)

Headers(`<key>`, `<value>`) — Matcht Requests anhand eines Header-Werts.

Headers(`X-Custom-Header`, `special-value`)

HostRegexp(`{subdomain:[a-z]+}.example.com`) — Matcht Hostnamen per regulärem Ausdruck.

HostRegexp(`{subdomain:[a-z]+}.example.com`)

ClientIP(`<cidr>`) — Matcht Requests aus bestimmten Client-IP-Bereichen.

ClientIP(`10.0.0.0/8`)

Fazit

Traefik nimmt dir den Großteil der manuellen Proxy-Pflege ab: Neue Container tauchen über Labels automatisch als Router und Services auf, und Let's-Encrypt-Zertifikate werden ohne Cronjob ausgestellt und erneuert. Halte sauber getrennt, was statisch ist (EntryPoints, Provider, Resolver) und was dynamisch kommt (Labels oder File-Provider) – dann bleibt deine Konfiguration auch bei vielen Diensten überschaubar. Und denk an die Basics der Absicherung: Dashboard nicht ungeschützt exponieren und den Docker-Socket nur lesend einbinden.

Verwandte Kommandos

  • apache – klassischer Webserver, auch als Reverse Proxy einsetzbar
  • caddy – Webserver mit automatischem HTTPS, ähnlicher Ansatz
  • certbot – Let's-Encrypt-Zertifikate manuell verwalten