für lokale Docker-Stacks
Lokale Docker-Entwicklungsumgebungen mit mehreren Projekten brauchen einen Reverse Proxy, der Domains auf Container leitet und HTTPS-Zertifikate verwaltet. Traefik und nginx-proxy lösen dasselbe Problem mit fundamental unterschiedlichen Ansätzen. Dieser Beitrag zeigt, welcher Proxy in welchem Szenario die bessere Wahl ist.
Inhaltsverzeichnis
- 1. Das Problem: Mehrere Projekte, ein lokaler Stack
- 2. nginx-proxy: Einfach, stabil, konfigurationsarm
- 3. Traefik: Dynamisch, label-gesteuert, mit Dashboard
- 4. HTTPS lokal: mkcert, Zertifikate und Browser-Vertrauen
- 5. Multi-Projekt-Setup: Gemeinsames Netzwerk und DNS
- 6. Traefik-Labels im Detail: Routing und Middleware
- 7. nginx-proxy mit angepasster nginx-Konfiguration
- 8. Direkter Vergleich: Traefik vs. nginx-proxy
- 9. Empfehlung: Welcher Proxy für welches Setup
- 10. Zusammenfassung
- 11. FAQ
1. Das Problem: Mehrere Projekte, ein lokaler Stack
In der lokalen Entwicklung entstehen schnell Situationen, die einen Reverse Proxy erfordern: Mehrere Projekte sollen gleichzeitig laufen und über sinnvolle Domains wie shop.local und api.local erreichbar sein statt über localhost:8080 und localhost:8081. HTTPS soll funktionieren, weil bestimmte Browser-Features wie Service Workers und Cookies mit SameSite=Strict HTTPS voraussetzen. Und wenn ein neues Projekt gestartet wird, soll es automatisch unter seiner Domain erreichbar sein, ohne die Proxy-Konfiguration manuell anzupassen.
Zwei Tools haben sich als Standard für dieses Szenario etabliert: Traefik und nginx-proxy (das nginxproxy/nginx-proxy-Image). Beide lauschen auf dem Docker-Socket, entdecken neue Container und konfigurieren das Routing automatisch. Der Unterschied liegt im Ansatz: nginx-proxy generiert aus Container-Umgebungsvariablen eine Nginx-Konfigurationsdatei und lädt Nginx bei Container-Ereignissen neu. Traefik liest Labels aus Container-Definitionen, hält eine dynamische Routing-Konfiguration und stellt ein Web-Dashboard bereit.
Die Wahl zwischen Traefik und nginx-proxy ist nicht universal richtig oder falsch. Wer ein einfaches Setup mit minimalem Konfigurationsaufwand sucht und keine komplexen Routing-Regeln braucht, ist mit nginx-proxy gut bedient. Wer dynamisches Routing, Middleware-Konfiguration (Rate Limiting, Header-Manipulation, Auth) und ein visuelles Dashboard braucht, wählt Traefik. Beide Proxys können produktive HTTPS-Zertifikate in der Produktion verwalten – aber in diesem Beitrag liegt der Fokus auf dem lokalen Entwicklungssetup.
2. nginx-proxy: Einfach, stabil, konfigurationsarm
nginx-proxy ist das ältere und einfachere der beiden Tools. Es lauscht auf dem Docker-Socket und generiert automatisch eine Nginx-Upstream- und Server-Block-Konfiguration aus der Umgebungsvariablen VIRTUAL_HOST der Container. Wenn ein Container mit VIRTUAL_HOST=shop.local gestartet wird, erscheint in der generierten Nginx-Konfiguration ein neuer Server-Block, der Anfragen an shop.local an den Container weiterleitet. Das ist der gesamte Konfigurationsaufwand auf Container-Seite.
Der Vorteil von nginx-proxy ist die Transparenz: Die generierte Nginx-Konfiguration ist sichtbar und verständlich. Wenn etwas nicht funktioniert, kann man docker exec nginx-proxy cat /etc/nginx/conf.d/default.conf ausführen und die generierte Konfiguration lesen. Es gibt keine Abstraktionsebene. Für Teams, die mit Nginx vertraut sind und keine Label-gesteuerte Konfiguration lernen wollen, ist das ein erheblicher Vorteil. nginx-proxy ist auch stabiler in Bezug auf Breaking Changes – es tut genau eine Sache und tut sie zuverlässig.
Die Einschränkungen von nginx-proxy sind direkte Folge seiner Einfachheit: Komplexe Routing-Regeln – etwa das Weiterleiten bestimmter URL-Pfade an verschiedene Backend-Container – sind schwierig oder erfordern eigene Nginx-Konfigurationsfragmente. Middleware-Features wie automatisches HTTP-zu-HTTPS-Redirect oder Rate Limiting brauchen manuelle Konfiguration. Für einfache Domain-zu-Container-Weiterleitung ist nginx-proxy optimal; für komplexere Szenarien wird Traefik zum überlegenen Werkzeug.
3. Traefik: Dynamisch, label-gesteuert, mit Dashboard
Traefik verfolgt einen fundamental anderen Ansatz: Statt Konfiguration zu generieren, liest Traefik Labels direkt aus Container-Definitionen und konfiguriert Routing dynamisch ohne Reload. Ein Container mit dem Label traefik.http.routers.shop.rule=Host('shop.local') ist sofort nach dem Start unter shop.local erreichbar. Das Hinzufügen oder Entfernen von Containern aktualisiert die Traefik-Konfiguration ohne Unterbrechung – kein Nginx-Reload, keine kurze Downtime.
Das Traefik-Dashboard unter http://localhost:8080 zeigt alle konfigurierten Router, Services und Middlewares in Echtzeit. Das ist besonders wertvoll beim Debugging von Routing-Problemen: Man sieht sofort, ob ein Container erkannt wurde, ob die Labels korrekt geparst wurden und ob der Service als gesund gilt. nginx-proxy bietet kein vergleichbares Diagnose-Interface.
Traefik-Middlewares sind eines der mächtigsten Features: Mit einem einzigen Label kann ein Rate-Limiter, eine Basic-Auth, ein Header-Redirect oder eine IP-Whitelist auf einen Router angewendet werden. In der lokalen Entwicklung ist der automatische HTTP-zu-HTTPS-Redirect die häufigste Middleware: Ein Label aktiviert ihn global für alle Routen. Das ersetzt manuelle Nginx-Konfiguration für jedes Projekt einzeln durch eine zentrale Middleware-Definition, die von allen Projekten durch Referenz genutzt wird.
# docker-compose.yml — Traefik as local reverse proxy with HTTPS
services:
traefik:
image: traefik:v3.0
restart: unless-stopped
command:
# Enable Docker provider — watch Docker socket for container events
- "--providers.docker=true"
- "--providers.docker.exposedByDefault=false"
- "--providers.docker.network=traefik-proxy"
# HTTP entrypoint on port 80
- "--entrypoints.web.address=:80"
# HTTPS entrypoint on port 443
- "--entrypoints.websecure.address=:443"
# Enable dashboard (insecure mode — local only)
- "--api.insecure=true"
# TLS certificates from file provider (mkcert)
- "--providers.file.directory=/certs"
- "--providers.file.watch=true"
ports:
- "80:80"
- "443:443"
- "8080:8080" # Traefik dashboard
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./certs:/certs:ro # mkcert-generated certificates
networks:
- traefik-proxy
networks:
traefik-proxy:
external: true
name: traefik-proxy
4. HTTPS lokal: mkcert, Zertifikate und Browser-Vertrauen
Lokales HTTPS mit echtem Browser-Vertrauen ist mit mkcert in wenigen Minuten eingerichtet. mkcert erstellt eine lokale Certificate Authority (CA) und installiert sie in den Browser-Vertrauensspeicher des Systems. Danach erzeugte Zertifikate werden vom Browser als vertrauenswürdig eingestuft – keine SSL-Warnungen, kein Klicken durch Sicherheitswarndialoge. Das ist deutlich sauberer als selbst signierte Zertifikate, die manuell zu Ausnahmen hinzugefügt werden müssen.
Das mkcert-Zertifikat kann als Wildcard-Zertifikat für *.local oder spezifisch für verwendete Domains ausgestellt werden. Mit Traefik wird das Zertifikat über einen File-Provider eingebunden: Eine YAML-Datei im Certificates-Verzeichnis definiert, welches Zertifikat für welche Domain verwendet wird. Traefik überwacht dieses Verzeichnis und lädt Zertifikate automatisch neu, wenn sie sich ändern. Das ermöglicht es, Zertifikate zu rotieren ohne Traefik neu zu starten.
nginx-proxy unterstützt HTTPS über das separate Companion-Container-System: acme-companion verwaltet Let's Encrypt-Zertifikate für Produktionsumgebungen, nginx-proxy-certs ermöglicht manuelle Zertifikate für die lokale Entwicklung. Das Zertifikat wird als Datei in ein Volume gelegt, das mit dem Proxy-Container geteilt wird. Beide Ansätze funktionieren gut; der Traefik-File-Provider ist etwas flexibler beim automatischen Reload.
# Setup: mkcert for local HTTPS — run once per developer machine
# Install mkcert (Linux)
curl -JLO "https://dl.filippo.io/mkcert/latest?for=linux/amd64"
chmod +x mkcert-v*-linux-amd64
sudo mv mkcert-v*-linux-amd64 /usr/local/bin/mkcert
# Install local CA into system/browser trust stores
mkcert -install
# Generate wildcard certificate for local domains
mkdir -p ~/docker-certs
cd ~/docker-certs
mkcert "*.local" "*.dev.local" "localhost" "127.0.0.1"
# Creates: _wildcard.local+2.pem and _wildcard.local+2-key.pem
# Traefik dynamic TLS config (certs/tls.yml — watched by Traefik)
cat > ~/docker-certs/tls.yml << 'EOF'
tls:
certificates:
- certFile: /certs/_wildcard.local+2.pem
keyFile: /certs/_wildcard.local+2-key.pem
stores:
default:
defaultCertificate:
certFile: /certs/_wildcard.local+2.pem
keyFile: /certs/_wildcard.local+2-key.pem
EOF
5. Multi-Projekt-Setup: Gemeinsames Netzwerk und DNS
Der Kern eines funktionierenden Multi-Projekt-Setups mit lokalem Reverse Proxy ist ein gemeinsames externes Docker-Netzwerk. Der Proxy-Container ist Mitglied dieses Netzwerks, und jedes Projekt-Compose-Datei verbindet seine Haupt-Services ebenfalls damit. Das ermöglicht dem Proxy, die Container aller Projekte zu sehen und Anfragen weiterzuleiten, ohne dass alle Projekte in derselben Compose-Datei definiert sein müssen.
Das externe Netzwerk wird einmalig mit docker network create traefik-proxy erstellt. In der Compose-Datei jedes Projekts wird es als externes Netzwerk referenziert: networks: traefik-proxy: external: true. Der jeweilige Service des Projekts verbindet sich sowohl mit dem projektinternen Netzwerk (für Kommunikation mit Datenbank und Cache) als auch mit dem externen Proxy-Netzwerk (für Erreichbarkeit durch den Proxy).
Für die Domain-Auflösung gibt es zwei Ansätze: Eine statische /etc/hosts-Datei mit Einträgen für alle verwendeten lokalen Domains, oder ein lokales DNS-Tool wie dnsmasq, das alle .local-Anfragen auf 127.0.0.1 auflöst. Letzteres ist flexibler – neue Projekte mit neuen Subdomains funktionieren automatisch, ohne /etc/hosts anzupassen. Auf macOS ist Resolver-Unterstützung für .local-Domains über /etc/resolver/local die empfohlene Lösung.
6. Traefik-Labels im Detail: Routing und Middleware
Traefik-Labels in Docker Compose folgen einem konsistenten Schema: traefik.http.routers.NAME.rule definiert die Routing-Regel, traefik.http.routers.NAME.service verweist auf einen Service, traefik.http.services.NAME.loadbalancer.server.port definiert den Port des Backends. Für einfache Setups reicht die Routing-Regel mit Host('domain.local'). Für HTTPS kommen traefik.http.routers.NAME.tls=true und eine Referenz auf einen Entrypoint hinzu.
Middlewares in Traefik sind wiederverwendbare Konfigurationsbausteine. Eine globale HTTP-zu-HTTPS-Redirect-Middleware wird einmalig in der Traefik-Konfiguration oder als Label in einem separaten Container definiert und dann durch Namensreferenz in jedem Router aktiviert. Das spart erheblich Konfigurationsaufwand gegenüber nginx-proxy, wo der Redirect für jeden Container separat konfiguriert werden muss.
# docker-compose.yml — Project service with Traefik labels for HTTPS routing
services:
app:
image: ghcr.io/myorg/myapp:latest
networks:
- internal
- traefik-proxy
labels:
# Enable Traefik for this container
- "traefik.enable=true"
# HTTP router: redirect to HTTPS
- "traefik.http.routers.shop-http.rule=Host(`shop.local`)"
- "traefik.http.routers.shop-http.entrypoints=web"
- "traefik.http.routers.shop-http.middlewares=redirect-https"
# HTTPS router
- "traefik.http.routers.shop-https.rule=Host(`shop.local`)"
- "traefik.http.routers.shop-https.entrypoints=websecure"
- "traefik.http.routers.shop-https.tls=true"
# Backend service port
- "traefik.http.services.shop.loadbalancer.server.port=8080"
# Network to use for upstream connection
- "traefik.docker.network=traefik-proxy"
db:
image: mysql:8.4
networks:
- internal # DB stays in internal network only — not exposed to proxy
# Shared redirect middleware (define once, reference everywhere)
# Can also be defined in traefik static config:
# traefik.http.middlewares.redirect-https.redirectscheme.scheme=https
networks:
internal:
traefik-proxy:
external: true
name: traefik-proxy
7. nginx-proxy mit angepasster nginx-Konfiguration
Trotz seiner Einfachheit bietet nginx-proxy Erweiterungspunkte für projektspezifische Nginx-Konfiguration. Im Volume /etc/nginx/vhost.d/ können Dateien abgelegt werden, die den generierten Server-Block für eine bestimmte Domain ergänzen. Eine Datei namens shop.local in diesem Verzeichnis wird automatisch in den Server-Block für shop.local eingebunden. Das ermöglicht projektspezifische Buffer-Größen, Timeout-Werte, client_max_body_size oder Custom-Header.
Für die HTTPS-Konfiguration mit nginx-proxy und mkcert werden die Zertifikate als Dateien in das Volume /etc/nginx/certs/ gelegt. Das Naming-Schema ist entscheidend: shop.local.crt und shop.local.key werden automatisch dem Server-Block für shop.local zugeordnet. nginx-proxy erkennt die Zertifikate und aktiviert TLS für den entsprechenden Server-Block automatisch. Das ist weniger flexibel als der Traefik-File-Provider, aber für einfache Setups ausreichend.
Ein häufiges Problem mit nginx-proxy tritt auf, wenn ein Container für HTTPS konfiguriert ist, aber das Zertifikat fehlt oder noch nicht bereit ist. nginx-proxy generiert dann keinen HTTPS-Server-Block und der Container ist nur über HTTP erreichbar, ohne offensichtliche Fehlermeldung. Das Debugging erfordert einen Blick in die generierte Nginx-Konfiguration. Bei Traefik würde das Dashboard sofort zeigen, dass kein Zertifikat für den Route konfiguriert ist.
8. Direkter Vergleich: Traefik vs. nginx-proxy
Der Vergleich zwischen Traefik und nginx-proxy lässt sich entlang mehrerer Dimensionen ziehen, die für die lokale Entwicklung relevant sind.
| Dimension | nginx-proxy | Traefik | Vorteil |
|---|---|---|---|
| Einstiegshürde | Sehr gering (VIRTUAL_HOST) | Labels-Schema lernen | nginx-proxy für Einstieg |
| Dynamisches Routing | Nginx-Reload bei Änderungen | Kein Reload nötig | Traefik für dynamische Setups |
| Debugging | Generierte conf lesen | Dashboard + Logs | Traefik für bessere Einsicht |
| Middleware | Manuelle nginx-Konfiguration | Labels, wiederverwendbar | Traefik für komplexe Regeln |
| Stabilität | Sehr stabil, wenig Breaking Changes | Breaking Changes zwischen Versionen | nginx-proxy für Low-Maintenance |
Beide Tools haben ihren Platz. nginx-proxy ist die bessere Wahl für Entwickler, die einen Proxy schnell aufsetzen und nicht mehr darüber nachdenken wollen. Traefik ist die bessere Wahl für Teams, die ihren lokalen Stack aktiv konfigurieren, mehrere Projekte gleichzeitig betreiben und das Dashboard als Debugging-Werkzeug schätzen. Für Produktionsumgebungen verschiebt sich die Abwägung: Traefik hat dort mit automatischer Let's Encrypt-Integration und Kubernetes-CRD-Support erhebliche Vorteile.
9. Empfehlung: Welcher Proxy für welches Setup
Wähle nginx-proxy, wenn: Das Setup aus wenigen festen Projekten besteht die selten hinzugefügt oder entfernt werden. Das Team ist mit Nginx vertraut. Die Anforderungen an Routing und Middleware sind einfach. Schnelles, wartungsarmes Setup ist wichtiger als Features.
Wähle Traefik, wenn: Mehrere Projekte dynamisch gestartet und gestoppt werden. Middleware-Features wie automatischer HTTPS-Redirect, Rate Limiting oder Auth benötigt werden. Das Dashboard als Debugging-Werkzeug genutzt werden soll. Der Stack für Produktion vorbereitet werden soll und Konsistenz zwischen lokaler Entwicklung und Produktion gewünscht ist.
Für das Mark-Shust-Magento-Docker-Setup ist nginx-proxy die bewährtere Wahl: Das Setup ist auf ein Projekt ausgelegt, die Konfiguration ist minimal und das Verhalten ist vorhersehbar. Wer mehrere Magento-Projekte gleichzeitig betreibt und zwischen ihnen wechselt, profitiert von Traefiks dynamischer Service-Discovery. In diesem Fall lohnt es sich, das Traefik-Netzwerk als globalen Standard einzuführen und alle Projekte damit zu verbinden.
Mironsoft
Lokale Entwicklungsumgebungen, Reverse Proxy und Docker-Setups
Lokale Entwicklungsumgebung mit HTTPS und Multi-Projekt-Routing?
Wir richten lokale Docker-Stacks mit Traefik oder nginx-proxy, mkcert-Zertifikaten und Multi-Projekt-Netzwerken ein – für produktive Entwicklungsworkflows ohne Portkonflikt-Chaos.
Proxy-Setup
Traefik oder nginx-proxy mit HTTPS, mkcert und Multi-Projekt-Routing einrichten
Dev-Umgebung
Magento, Shopware und andere Projekte gleichzeitig lokal betreiben
Team-Onboarding
Reproduzierbare Entwicklungsumgebung die auf jedem Entwickler-Rechner identisch läuft
10. Zusammenfassung
Traefik und nginx-proxy lösen dasselbe Problem mit unterschiedlichen Philosophien. nginx-proxy ist transparent, stabil und mit minimalem Konfigurationsaufwand einsatzbereit – ideal für Teams, die einen wartungsarmen Proxy ohne Lernkurve suchen. Traefik ist dynamisch, feature-reich und bietet mit dem Dashboard und der Label-basierten Konfiguration erheblich mehr Flexibilität für komplexe Multi-Projekt-Setups.
HTTPS lokal mit mkcert ist mit beiden Proxys in wenigen Minuten eingerichtet und beseitigt das klassische Problem mit selbst signierten Zertifikaten im Browser. Das gemeinsame externe Docker-Netzwerk als Grundlage des Multi-Projekt-Setups ist unabhängig vom gewählten Proxy die richtige Architektur: Der Proxy hat Zugriff auf alle Projekt-Container, die Projekte behalten ihre interne Netzwerk-Isolation für Datenbankzugriffe und andere interne Services.
Traefik vs. nginx-proxy — Das Wichtigste auf einen Blick
nginx-proxy wählen wenn
Feste wenige Projekte, Nginx-Kenntnisse vorhanden, minimaler Konfigurationsaufwand gewünscht, Low-Maintenance-Setup bevorzugt.
Traefik wählen wenn
Dynamische Projektanzahl, Middleware-Features gewünscht, Dashboard für Debugging geschätzt, Konsistenz mit Produktions-Traefik gewünscht.
HTTPS lokal
mkcert -install, dann Wildcard-Zertifikat für *.local. Traefik: File-Provider. nginx-proxy: Zertifikat in /etc/nginx/certs/ Volume.
Multi-Projekt-Netzwerk
docker network create traefik-proxy. In jeder Compose-Datei als external: true referenzieren. Proxy ist Mitglied, Services verbinden sich damit.