Traefik v3 mit Docker Compose — Reverse Proxy in 10 Minuten

Tobias Krug Docker, Self-Hosting, Traefik
Traefik v3 mit Docker Compose — Reverse Proxy in 10 Minuten

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.

Traefik v3 als Reverse Proxy mit Docker Compose – Server-Rack mit Netzwerkkabeln
DatumÄnderungen
14.04.2026Kapitel 7 in Absicherung mit CrowdSec oder Fail2ban umbenannt
14.04.2026Kapitel 7 umbenannt und Unterpunkte nummeriert (7.1-7.6)
14.04.2026Socket-Proxy ins Setup integriert, Uptime-Kuma-Beispiel entfernt (Dashboard ist erster Service)
14.04.2026Neues Kapitel: Angriffsschutz mit CrowdSec
14.04.2026Auf Traefik v3.6 und Debian 13 Trixie aktualisiert
12.04.2026Anleitung überarbeitet und neu strukturiert
10.04.2026Anleitung 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: false bedeutet: Nur Container mit dem Label traefik.enable=true werden 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
0 0 Bewertungen
Beitragsbewertung
Abonnieren
Benachrichtigen bei
guest
0 Kommentare
Älteste
Neueste Meistbewertet
Inline-Feedbacks
Alle Kommentare anzeigen