Traefik als Reverse Proxy mit Docker - Labels statt Konfigurationsdateien
Traefik als Reverse Proxy mit Docker - Labels statt Konfigurationsdateien
Traefik erkennt Docker-Container automatisch über Labels und konfiguriert sich selbst — kein Nginx-Reload, keine statischen Configs.
Wie Traefik mit Docker funktioniert
Traefik hört auf den Docker-Socket und liest Labels von laufenden Containern. Wenn ein Container mit dem richtigen Label startet, wird er automatisch als Backend registriert. Stoppt er, wird er entfernt. Alles ohne manuelle Konfiguration.
Traefik-Container einrichten
services:
traefik:
image: traefik:v3.0
command:
- "--api.dashboard=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false" # Container müssen sich explizit anmelden
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.letsencrypt.acme.email=admin@example.com"
- "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
- "--certificatesresolvers.letsencrypt.acme.tlschallenge=true"
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- letsencrypt:/letsencrypt
labels:
- "traefik.enable=true"
- "traefik.http.routers.dashboard.rule=Host(`traefik.example.com`)"
- "traefik.http.routers.dashboard.service=api@internal"
- "traefik.http.routers.dashboard.entrypoints=websecure"
- "traefik.http.routers.dashboard.tls.certresolver=letsencrypt"
volumes:
letsencrypt:
exposedbydefault=false ist wichtig: Ohne dieses Flag würde Traefik jeden Container exponieren — das ist ein Sicherheitsrisiko.
App-Container mit Labels konfigurieren
services:
app:
image: myapp
labels:
- "traefik.enable=true"
- "traefik.http.routers.myapp.rule=Host(`app.example.com`)"
- "traefik.http.routers.myapp.entrypoints=websecure"
- "traefik.http.routers.myapp.tls.certresolver=letsencrypt"
- "traefik.http.services.myapp.loadbalancer.server.port=3000"
networks:
- traefik-public
- internal
db:
image: postgres:16
# Kein traefik.enable — nicht exponiert
networks:
- internal
networks:
traefik-public:
external: true # Vom Traefik-Stack erstellt
internal:
Das Label loadbalancer.server.port teilt Traefik mit, auf welchem Port die App intern lauscht — auch wenn der Container keinen ports:-Block hat.
HTTP zu HTTPS umleiten
labels:
- "traefik.http.routers.myapp-http.rule=Host(`app.example.com`)"
- "traefik.http.routers.myapp-http.entrypoints=web"
- "traefik.http.routers.myapp-http.middlewares=redirect-https"
- "traefik.http.middlewares.redirect-https.redirectscheme.scheme=https"
- "traefik.http.middlewares.redirect-https.redirectscheme.permanent=true"
Middleware: Authentifizierung
Traefik unterstützt BasicAuth direkt über Labels:
# Passwort-Hash generieren
echo $(htpasswd -nb admin secretpassword)
# Ausgabe: admin:$apr1$...
labels:
- "traefik.http.middlewares.auth.basicauth.users=admin:$$apr1$$..." # $$ escapt das $
- "traefik.http.routers.myapp.middlewares=auth"
Traefik-Dashboard
Das Dashboard unter traefik.example.com (oder lokal auf Port 8080 mit --api.insecure=true) zeigt alle erkannten Routers, Services und Middlewares in Echtzeit — nützlich zur Fehlersuche.
# Lokal ohne TLS zum Testen
docker run traefik --api.insecure=true --providers.docker -p 80:80 -p 8080:8080 \
-v /var/run/docker.sock:/var/run/docker.sock
Gemeinsames Netzwerk zwischen Stacks
Für mehrere Compose-Stacks auf einem Host:
docker network create traefik-public
Jeder Stack referenziert dieses Netzwerk als external: true. Traefik muss im selben Netzwerk sein wie die Ziel-Container — sonst kann er sie nicht erreichen.
Traefik ist besonders stark, wenn viele Dienste dynamisch kommen und gehen. Für statische Setups mit wenigen Diensten ist Nginx manchmal einfacher.