Wer mehrere Services auf einem Server betreibt, braucht einen Reverse Proxy. Traefik v3 übernimmt das automatisch: Es erkennt neue Docker-Container, liest deren Labels und stellt sie mit gültigem TLS-Zertifikat bereit. Kein manuelles Nginx-Config-Schreiben, kein certbot renew Cronjob.
In dieser Anleitung zeige ich, wie Traefik v3 mittels Docker Compose als Reverse Proxy mit automatischem Let’s Encrypt Zertifikat eingerichtet wird. Docker-Socket wird über einen Socket-Proxy abgesichert. Nach dem Setup lassen sich beliebige weitere Services mit wenigen Labels anbinden. Weitere Anleitungen findest du im Traefik-Archiv und zu Docker Compose auf diesem Blog.

| Datum | Änderungen |
|---|---|
| 14.04.2026 | Kapitel 7 in Absicherung mit CrowdSec oder Fail2ban umbenannt |
| 14.04.2026 | Kapitel 7 umbenannt und Unterpunkte nummeriert (7.1-7.6) |
| 14.04.2026 | Socket-Proxy ins Setup integriert, Uptime-Kuma-Beispiel entfernt (Dashboard ist erster Service) |
| 14.04.2026 | Neues Kapitel: Angriffsschutz mit CrowdSec |
| 14.04.2026 | Auf Traefik v3.6 und Debian 13 Trixie aktualisiert |
| 12.04.2026 | Anleitung überarbeitet und neu strukturiert |
| 10.04.2026 | Anleitung erstellt |
1. Grundvoraussetzung
Diese Anleitung wurde getestet mit Traefik v3.6 auf Debian 13 Trixie, sollte aber auch auf Ubuntu 22.04/24.04 funktionieren. Alle Befehle werden als Root-Benutzer ausgeführt.
- Docker & Docker Compose v2 installiert
- Eine Domain, die per A-Record auf den Server zeigt
- Port 80 und 443 offen
- Root- oder Sudo-Zugriff
2. Docker-Netzwerk anlegen
Traefik und alle Services, die darüber erreichbar sein sollen, müssen sich ein gemeinsames Netzwerk teilen:
docker network create proxy
Dieses Netzwerk wird in jeder docker-compose.yml als external: true referenziert.
3. Verzeichnisse anlegen
mkdir -p /opt/containers/traefik
cd /opt/containers/traefik/
4. Dateien erstellen
touch docker-compose.yml traefik.yml .env
touch acme.json && chmod 600 acme.json
Die acme.json speichert die Let’s Encrypt Zertifikate. Traefik erwartet 600er Rechte — andernfalls verweigert es den Start.
5. Inhalt der Dateien
5.1 .env Datei
nano /opt/containers/traefik/.env
Inhalt:
# Traefik Environment
TRAEFIK_DOMAIN=traefik.deine-domain.de
LETSENCRYPT_EMAIL=deine-email@example.com
# Basic Auth für Dashboard (htpasswd-Hash)
# Generieren mit: echo $(htpasswd -nB admin) | sed -e 's/$/$/g'
TRAEFIK_DASHBOARD_AUTH=admin:$2y$10$DEIN_HASH_HIER
⚠️ Wichtig: Ersetze traefik.deine-domain.de durch deine tatsächliche Subdomain und generiere einen eigenen htpasswd-Hash:
sudo apt install apache2-utils
echo $(htpasswd -nB admin) | sed -e 's/$/$/g'
Das doppelte $$ ist zwingend — Docker interpretiert einfache $ als Variable.
5.2 traefik.yml Datei (Statische Konfiguration)
nano /opt/containers/traefik/traefik.yml
Inhalt:
global:
checkNewVersion: false
sendAnonymousUsage: false
api:
dashboard: true
debug: false
entryPoints:
web:
address: ":80"
http:
redirections:
entryPoint:
to: websecure
scheme: https
permanent: true
websecure:
address: ":443"
providers:
docker:
endpoint: "tcp://socket-proxy:2375"
exposedByDefault: false
network: proxy
file:
filename: /traefik.yml
watch: true
certificatesResolvers:
http_resolver:
acme:
email: "${LETSENCRYPT_EMAIL}"
storage: /acme.json
httpChallenge:
entryPoint: web
Was hier passiert:
- HTTP → HTTPS Redirect: Alle Anfragen über Port 80 werden automatisch auf HTTPS umgeleitet
- Docker Provider: Traefik spricht den Docker-Daemon nicht direkt an, sondern über den Socket-Proxy auf
tcp://socket-proxy:2375.exposedByDefault: falsebedeutet: Nur Container mit dem Labeltraefik.enable=truewerden exponiert - Let’s Encrypt: Per HTTP-Challenge. Traefik erstellt und erneuert Zertifikate automatisch
5.3 docker-compose.yml Datei
nano /opt/containers/traefik/docker-compose.yml
Inhalt:
services:
socket-proxy:
image: tecnativa/docker-socket-proxy:latest
container_name: socket-proxy
restart: unless-stopped
environment:
CONTAINERS: 1
NETWORKS: 1
SERVICES: 1
TASKS: 1
POST: 0
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
networks:
- proxy
traefik:
image: traefik:v3.6
container_name: traefik
restart: unless-stopped
depends_on:
- socket-proxy
ports:
- "80:80"
- "443:443"
environment:
LETSENCRYPT_EMAIL: ${LETSENCRYPT_EMAIL}
volumes:
- ./traefik.yml:/traefik.yml:ro
- ./acme.json:/acme.json
networks:
- proxy
labels:
- "traefik.enable=true"
# Dashboard
- "traefik.http.routers.dashboard.rule=Host(`${TRAEFIK_DOMAIN}`)"
- "traefik.http.routers.dashboard.service=api@internal"
- "traefik.http.routers.dashboard.entrypoints=websecure"
- "traefik.http.routers.dashboard.tls.certresolver=http_resolver"
# Basic Auth
- "traefik.http.routers.dashboard.middlewares=auth"
- "traefik.http.middlewares.auth.basicauth.users=${TRAEFIK_DASHBOARD_AUTH}"
networks:
proxy:
external: true
Der Socket-Proxy (tecnativa/docker-socket-proxy) bekommt als einziger Container den Docker-Socket read-only gemounted und stellt nur die Endpoints bereit, die Traefik wirklich braucht: Container, Networks, Services und Tasks — alles nur lesend. POST: 0 verhindert, dass über den Proxy Container gestartet, gestoppt oder verändert werden können. Fällt Traefik einem Angriff zum Opfer, hat der Angreifer keinen direkten Zugriff mehr auf den Docker-Daemon.
6. Traefik v3 starten
cd /opt/containers/traefik
docker compose up -d
Die Logs prüfen:
docker logs traefik -f
docker logs socket-proxy -f
Es sollte keine Fehlermeldung erscheinen. Nach wenigen Sekunden ist das Dashboard unter https://traefik.deine-domain.de erreichbar — Login mit den Basic-Auth-Credentials aus der .env. Das Dashboard ist damit gleichzeitig der erste Service, der über Traefik exponiert wird — jeder weitere Container wird nach dem gleichen Muster mit Labels angebunden.
7. Absicherung mit CrowdSec oder Fail2ban
Traefik steht jetzt öffentlich erreichbar im Netz. Zeit, ein bisschen Gegenwehr einzubauen. CrowdSec ist ein Open-Source-IPS, das Logs analysiert, bösartige IPs erkennt und gleichzeitig eine kollektive Blocklist der Community nutzt. Kostenlos, keine Lizenz, läuft als Container neben Traefik.
Die Integration besteht aus zwei Teilen:
- Der CrowdSec-Agent liest die Traefik-Access-Logs und entscheidet, wer gesperrt wird
- Der Traefik-Bouncer (als Plugin) fragt pro Request nach, ob die IP blockiert ist
Alternative: Wer es minimalistischer mag, greift zu Fail2ban mit dem traefik-plugin-fail2ban. Rein lokal, keine Community-Intel, aber leichtgewichtig. Für das folgende Setup bleibe ich bei CrowdSec, weil die Blocklist out of the box mitgeliefert wird.
7.1 Access-Log in Traefik aktivieren
CrowdSec braucht Logs zum Auswerten. In der traefik.yml folgendes ergänzen:
accessLog:
filePath: "/var/log/traefik/access.log"
format: json
bufferingSize: 0
Im docker-compose.yml des Traefik-Containers ein Volume für die Logs ergänzen:
volumes:
- ./traefik.yml:/traefik.yml:ro
- ./acme.json:/acme.json
- ./logs:/var/log/traefik
7.2 CrowdSec-Container starten
In /opt/containers/crowdsec eine neue docker-compose.yml:
services:
crowdsec:
image: crowdsecurity/crowdsec:latest
container_name: crowdsec
restart: unless-stopped
environment:
COLLECTIONS: "crowdsecurity/traefik crowdsecurity/http-cve crowdsecurity/linux"
GID: "1000"
volumes:
- ./data:/var/lib/crowdsec/data
- ./config:/etc/crowdsec
- /opt/containers/traefik/logs:/var/log/traefik:ro
networks:
- proxy
networks:
proxy:
external: true
Die Acquisition-Datei sagt CrowdSec, welche Logs er lesen soll. Vor dem ersten Start anlegen unter /opt/containers/crowdsec/config/acquis.yaml:
filenames:
- /var/log/traefik/*.log
labels:
type: traefik
Starten:
cd /opt/containers/crowdsec
docker compose up -d
docker logs crowdsec -f
7.3 Traefik-Bouncer als Plugin registrieren
Damit Traefik pro Request bei CrowdSec nachfragt, kommt das offizielle Plugin dazu. In der traefik.yml ergänzen:
experimental:
plugins:
bouncer:
moduleName: "github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin"
version: "v1.4.4"
Traefik einmal neu starten, damit das Plugin geladen wird:
cd /opt/containers/traefik
docker compose up -d
7.4 API-Key erzeugen und Middleware anlegen
Im laufenden CrowdSec-Container einen Bouncer-Key holen:
docker exec crowdsec cscli bouncers add traefik-bouncer
Den ausgegebenen Key kopieren. Jetzt eine dynamische Config anlegen unter /opt/containers/traefik/dynamic/crowdsec.yml und in der traefik.yml den Provider hinzufügen:
providers:
file:
directory: /dynamic
watch: true
Inhalt der crowdsec.yml:
http:
middlewares:
crowdsec:
plugin:
bouncer:
enabled: true
crowdsecMode: "live"
crowdsecLapiKey: "HIER_DEN_API_KEY_EINSETZEN"
crowdsecLapiHost: "crowdsec:8080"
crowdsecLapiScheme: "http"
Das Volume-Mount in docker-compose.yml von Traefik nicht vergessen:
- ./dynamic:/dynamic:ro
7.5 Middleware an Services hängen
Ab jetzt einfach bei jedem Service das Label setzen:
- "traefik.http.routers.SERVICE.middlewares=crowdsec@file"
7.6 Funktioniert’s?
Ein paar absichtlich schlechte Requests schicken und schauen, ob CrowdSec reagiert:
for i in {1..20}; do curl -s -o /dev/null https://deine-domain.de/.env; done
docker exec crowdsec cscli decisions list
Mit etwas Glück taucht die eigene IP kurz darauf in der Liste auf — dann funktioniert die Kette. Mit cscli decisions delete --ip DEINE_IP kommst du wieder rein.
Die Community-Blocklist zieht sich CrowdSec automatisch, sobald die Instance beim CrowdSec Console (kostenlos) registriert ist — macht aber nichts, wenn man das erstmal überspringt. Lokale Regeln reichen für den Start.
8. Zusammenfassung: Reverse Proxy mit Docker Compose
| Schritt | Befehl |
|---|---|
| Netzwerk anlegen | `docker network create proxy` |
| Verzeichnis anlegen | `mkdir -p /opt/containers/traefik && cd /opt/containers/traefik/` |
| Dateien erstellen | `touch docker-compose.yml traefik.yml .env && touch acme.json && chmod 600 acme.json` |
| Traefik starten | `docker compose up -d` |
| Logs prüfen | `docker logs traefik -f` |
| Weitere Services anbinden | Labels in der docker-compose.yml des Services setzen |
Was als nächstes?
Dieses Setup ist die Basis. Für den produktiven Einsatz empfehlen sich zusätzlich:
- Security Headers: Via Traefik Middleware oder dynamischer Konfiguration
- Rate Limiting: Schutz vor Brute-Force und DDoS
- Authelia / Authentik: Single Sign-On für mehrere Services
