Traefik ist ein moderner, Cloud-nativer Reverse Proxy und Load Balancer. Er glänzt durch automatische Service Discovery und native Container-Integration.

Vorteile von Traefik

Features

- Automatische Service Discovery
- Native Docker/Kubernetes-Integration
- Automatische Let's Encrypt Zertifikate
- Middleware (Rate Limiting, Auth, etc.)
- Dashboard zur Überwachung
- Hot-Reload ohne Neustart

Vergleich mit Nginx

| Feature | Traefik | Nginx | |---------|---------|-------| | Container-Discovery | Automatisch | Manuell | | Let's Encrypt | Integriert | Certbot | | Konfiguration | Labels/API | Config-Dateien | | Dashboard | Integriert | Extern |

Installation mit Docker

docker-compose.yml

version: '3'

services:
  traefik:
    image: traefik:v3.0
    container_name: traefik
    command:
      - "--api.dashboard=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./traefik.yml:/etc/traefik/traefik.yml
      - ./acme.json:/acme.json
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.dashboard.rule=Host(`traefik.example.com`)"
      - "traefik.http.routers.dashboard.service=api@internal"
      - "traefik.http.routers.dashboard.middlewares=auth"
      - "traefik.http.middlewares.auth.basicauth.users=admin:$$apr1$$..."
    restart: unless-stopped

traefik.yml (Statische Konfiguration)

# /etc/traefik/traefik.yml

api:
  dashboard: true
  insecure: false

entryPoints:
  web:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https

  websecure:
    address: ":443"

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

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

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

Container mit Traefik

Einfacher Service

# docker-compose.yml

services:
  whoami:
    image: traefik/whoami
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.whoami.rule=Host(`whoami.example.com`)"
      - "traefik.http.routers.whoami.entrypoints=websecure"
      - "traefik.http.routers.whoami.tls.certresolver=letsencrypt"

Web-Anwendung mit SSL

services:
  webapp:
    image: nginx
    labels:
      - "traefik.enable=true"
      # Router
      - "traefik.http.routers.webapp.rule=Host(`app.example.com`)"
      - "traefik.http.routers.webapp.entrypoints=websecure"
      - "traefik.http.routers.webapp.tls.certresolver=letsencrypt"
      # Service
      - "traefik.http.services.webapp.loadbalancer.server.port=80"

Multiple Domains

services:
  website:
    image: nginx
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.website.rule=Host(`example.com`) || Host(`www.example.com`)"
      - "traefik.http.routers.website.entrypoints=websecure"
      - "traefik.http.routers.website.tls.certresolver=letsencrypt"

Path-basiertes Routing

services:
  api:
    image: my-api
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.api.rule=Host(`example.com`) && PathPrefix(`/api`)"
      - "traefik.http.routers.api.entrypoints=websecure"
      - "traefik.http.middlewares.api-stripprefix.stripprefix.prefixes=/api"
      - "traefik.http.routers.api.middlewares=api-stripprefix"

  frontend:
    image: my-frontend
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.frontend.rule=Host(`example.com`)"
      - "traefik.http.routers.frontend.entrypoints=websecure"

Middlewares

Basic Auth

services:
  app:
    image: nginx
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.app.rule=Host(`app.example.com`)"
      - "traefik.http.routers.app.middlewares=auth"
      # Passwort mit: htpasswd -nb admin password
      - "traefik.http.middlewares.auth.basicauth.users=admin:$$apr1$$..."

Rate Limiting

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

IP Whitelist

labels:
  - "traefik.http.middlewares.ipwhitelist.ipwhitelist.sourcerange=192.168.1.0/24,10.0.0.0/8"
  - "traefik.http.routers.admin.middlewares=ipwhitelist"

Headers

labels:
  - "traefik.http.middlewares.security-headers.headers.frameDeny=true"
  - "traefik.http.middlewares.security-headers.headers.browserXssFilter=true"
  - "traefik.http.middlewares.security-headers.headers.contentTypeNosniff=true"
  - "traefik.http.middlewares.security-headers.headers.stsSeconds=31536000"
  - "traefik.http.routers.app.middlewares=security-headers"

Redirect Regex

labels:
  - "traefik.http.middlewares.www-redirect.redirectregex.regex=^https://www\\.(.+)"
  - "traefik.http.middlewares.www-redirect.redirectregex.replacement=https://$${1}"
  - "traefik.http.middlewares.www-redirect.redirectregex.permanent=true"

Compress

labels:
  - "traefik.http.middlewares.compress.compress=true"
  - "traefik.http.routers.app.middlewares=compress"

Chain (Mehrere Middlewares)

labels:
  - "traefik.http.middlewares.secured.chain.middlewares=security-headers,ratelimit,compress"
  - "traefik.http.routers.app.middlewares=secured"

Load Balancing

Mehrere Container

services:
  app:
    image: my-app
    deploy:
      replicas: 3
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.app.rule=Host(`app.example.com`)"
      - "traefik.http.services.app.loadbalancer.server.port=3000"

Sticky Sessions

labels:
  - "traefik.http.services.app.loadbalancer.sticky.cookie=true"
  - "traefik.http.services.app.loadbalancer.sticky.cookie.name=server_id"
  - "traefik.http.services.app.loadbalancer.sticky.cookie.httpOnly=true"

Health Checks

labels:
  - "traefik.http.services.app.loadbalancer.healthcheck.path=/health"
  - "traefik.http.services.app.loadbalancer.healthcheck.interval=10s"
  - "traefik.http.services.app.loadbalancer.healthcheck.timeout=3s"

Let's Encrypt

HTTP Challenge

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

DNS Challenge (Wildcard)

certificatesResolvers:
  letsencrypt:
    acme:
      email: admin@example.com
      storage: /acme.json
      dnsChallenge:
        provider: cloudflare
        resolvers:
          - "1.1.1.1:53"
# docker-compose.yml für Cloudflare
services:
  traefik:
    environment:
      - CF_API_EMAIL=admin@example.com
      - CF_API_KEY=your-api-key

Wildcard-Zertifikat verwenden

labels:
  - "traefik.http.routers.app.tls.certresolver=letsencrypt"
  - "traefik.http.routers.app.tls.domains[0].main=example.com"
  - "traefik.http.routers.app.tls.domains[0].sans=*.example.com"

File Provider (Statische Services)

Dynamische Konfiguration

# /etc/traefik/dynamic/services.yml

http:
  routers:
    external-api:
      rule: "Host(`api.example.com`)"
      service: external-api
      entryPoints:
        - websecure
      tls:
        certResolver: letsencrypt

  services:
    external-api:
      loadBalancer:
        servers:
          - url: "http://192.168.1.100:8080"
          - url: "http://192.168.1.101:8080"

TCP/UDP Services

# /etc/traefik/dynamic/tcp.yml

tcp:
  routers:
    mysql:
      rule: "HostSNI(`*`)"
      entryPoints:
        - mysql
      service: mysql

  services:
    mysql:
      loadBalancer:
        servers:
          - address: "192.168.1.50:3306"

Dashboard

Dashboard aktivieren

# traefik.yml
api:
  dashboard: true
  insecure: false

# docker-compose.yml Labels
labels:
  - "traefik.http.routers.traefik.rule=Host(`traefik.example.com`)"
  - "traefik.http.routers.traefik.service=api@internal"
  - "traefik.http.routers.traefik.entrypoints=websecure"
  - "traefik.http.routers.traefik.tls.certresolver=letsencrypt"
  - "traefik.http.routers.traefik.middlewares=auth"

Kubernetes

Traefik als Ingress Controller

# values.yaml für Helm

deployment:
  replicas: 2

ingressRoute:
  dashboard:
    enabled: true
    matchRule: Host(`traefik.example.com`)

providers:
  kubernetesIngress:
    enabled: true

certResolvers:
  letsencrypt:
    email: admin@example.com
    storage: /data/acme.json
    httpChallenge:
      entryPoint: web

IngressRoute CRD

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: myapp
spec:
  entryPoints:
    - websecure
  routes:
    - match: Host(`app.example.com`)
      kind: Rule
      services:
        - name: myapp
          port: 80
  tls:
    certResolver: letsencrypt

Logging und Monitoring

Access Logs

# traefik.yml
accessLog:
  filePath: "/var/log/traefik/access.log"
  format: json
  filters:
    statusCodes:
      - "400-499"
      - "500-599"

Metriken

# traefik.yml
metrics:
  prometheus:
    addEntryPointsLabels: true
    addServicesLabels: true
    buckets:
      - 0.1
      - 0.3
      - 1.2
      - 5.0

Tracing

# traefik.yml
tracing:
  jaeger:
    samplingServerURL: http://jaeger:5778/sampling
    localAgentHostPort: jaeger:6831

Vollständiges Beispiel

Production Setup

# docker-compose.yml

version: '3.8'

services:
  traefik:
    image: traefik:v3.0
    container_name: traefik
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./traefik.yml:/etc/traefik/traefik.yml:ro
      - ./dynamic:/etc/traefik/dynamic:ro
      - ./acme.json:/acme.json
      - ./logs:/var/log/traefik
    networks:
      - traefik
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.traefik.rule=Host(`traefik.example.com`)"
      - "traefik.http.routers.traefik.service=api@internal"
      - "traefik.http.routers.traefik.entrypoints=websecure"
      - "traefik.http.routers.traefik.tls.certresolver=letsencrypt"
      - "traefik.http.routers.traefik.middlewares=auth"
      - "traefik.http.middlewares.auth.basicauth.users=admin:$$apr1$$..."

  webapp:
    image: nginx
    networks:
      - traefik
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.webapp.rule=Host(`app.example.com`)"
      - "traefik.http.routers.webapp.entrypoints=websecure"
      - "traefik.http.routers.webapp.tls.certresolver=letsencrypt"
      - "traefik.http.routers.webapp.middlewares=security"
      - "traefik.http.middlewares.security.chain.middlewares=secure-headers,compress"
      - "traefik.http.middlewares.secure-headers.headers.framedeny=true"
      - "traefik.http.middlewares.compress.compress=true"

networks:
  traefik:
    external: true

Zusammenfassung

| Label | Funktion | |-------|----------| | traefik.enable | Service aktivieren | | traefik.http.routers.X.rule | Routing-Regel | | traefik.http.routers.X.entrypoints | Entrypoint | | traefik.http.routers.X.tls | SSL aktivieren | | traefik.http.routers.X.middlewares | Middlewares |

| Middleware | Funktion | |------------|----------| | basicauth | Authentifizierung | | ratelimit | Rate Limiting | | headers | Security Headers | | compress | Komprimierung | | stripprefix | Prefix entfernen |

| Entrypoint | Port | |------------|------| | web | 80 (HTTP) | | websecure | 443 (HTTPS) |

Fazit

Traefik ist ideal für Container-Umgebungen mit automatischer Service Discovery. Labels an Containern ersetzen manuelle Konfiguration. Let's Encrypt-Integration macht SSL trivial. Für Docker und Kubernetes ist Traefik oft die bessere Wahl als traditionelle Reverse Proxies. Das Dashboard bietet gute Übersicht über alle Services.