Reverse Proxy mit Traefik unter Docker

Traefik Architecture

Um mehrere Webseiten unter einer IP und einer Domain zu veröffentlichen, ist es am einfachsten, wenn man sich ein sogenannten reverse proxy einrichtet. Die wohl bekannte Variante dazu ist von NGINX. Hierfür gibt es auch diverse Tutorials im Internet.

Meine ganzen Services, die ich extern verfügbar machen möchte, laufen allerdings als Docker Container. Entsprechend bietet es sich an, auch den reverse proxy Traefik unter Docker als Container laufen zu lassen.

Auch hier gibt es für NGINX – auch in Kombination mit Let’s encrypt Zertifikaten – reichlich Tutorials. Ich hatte mich damals allerdings für einen anderen Weg entscheiden und Traefik als reverse proxy genommen.

Traefik Architecture

Wichtig ist natürlich, dass ihr in eurer Firewall bzw. Router ein NAT auf euren Docker Host einstellt. Port 80 (HTTP) und 443 (HTTPS) sollten entsprechend reichen.

Docker Container mittels Compose

Ich gehe erst mal davon aus, dass ihr Docker in einer der letzten Versionen installiert habt und eure Services, zumindest intern, vollständig funktionieren. Zudem nutze ich Docker Compose zum Verwalten meiner Container. Eine Adaption zu einem docker run command sollte kein Problem darstellen.

version: '3'

services:
  traefik:
    image: traefik:latest
    container_name: traefik
    restart: always
    ports:
      - 80:80
      - 443:443
      - 8080:8080
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./traefik:/etc/traefik
    environment:
      - "TZ=Europe/Berlin"
    networks:
      - traefik_proxy
      - default

networks:
  traefik_proxy:
    external:
      name: traefik_proxy
  default:
    driver: bridge

Ports 80 und 443 werden benötigt, um die entsprechenden Seiten dann auch weiterzuleiten. Port 8080 verwenden wir für das Webfrontend von Traefik. Ihr müsst also aufpassen, dass keine anderen Container diese Ports verwenden. Den Traefik Webport könnt ihr auch durch einen anderen ersetzen.

Zudem mounten wir als Volumes den Docker Socket, um Zugriff auf die laufenden Container zu haben. Als zweites Volume nutzen wir für die Konfigurationsdateien für Traefik.

Netzwerke legen wir an, um Traefik von außen erreichbar zu machen (default Netzwerk) und für das interne Routing zu Containern (traefik_proxy).

Traefik Konfiguration

Im Verzeichnis traefik legen wir nun noch die Datei traefik.toml an, welche folgenden Inhalt bekommt:

logLevel = "INFO"
  defaultEntryPoints = ["http", "https"]

[web]
  address = ":8080"

[docker]
  domain = "example.com"
  watch = true
  exposedbydefault = false

 # Force HTTPS
[entryPoints]
  [entryPoints.http]
  address = ":80"
    [entryPoints.http.redirect]
    entryPoint = "https"
  [entryPoints.https]
  address = ":443"
    [entryPoints.https.tls]

 # Let's encrypt configuration
 [acme]
   email="youremail.address@example.com"
   storage="/etc/traefik/acme/acme.json"
   entryPoint="https"
   acmeLogging=true
   OnHostRule=true
   [acme.httpChallenge]
     entryPoint = "http"

Wichtig ist, dass ihr eure Domain unter [docker] und eure Email Adresse unter [acme] richtig anpasst. Die Email Adresse wird für die Let’s encrypt Zertifikate benötigt.

Im Grundsätzlichen war es das schon für das Setup. Um jetzt Docker Container auch dazu zu bringen, auf die entsprechenden Domains zu hören, müssen wir die Konfiguration der einzelnen Container auch anpassen. Hier mal ein Beispiel von „The Lounge“ (einem IRC Frontend)

version: '3'

services:
  thelounge:
    image: thelounge/lounge:latest
    container_name: thelounge
    volumes:
      - /var/docker/thelounge:/home/lounge/data
    labels:
      - "traefik.backend=thelounge"
      - "traefik.enable=true"
      - "traefik.frontend.rule=Host:subdomain.example.com"
      - "traefik.port=9000"
      - "traefik.docker.network=traefik_proxy"
    networks:
      - traefik_proxy

networks:
  traefik_proxy:
    external:
      name: traefik_proxy
  default:
    driver: bridge

Folgende Werte müsst ihr pro Container anpassen:

  • traefik.backend (Name des Backends – könnt ihr frei vergeben)
  • traefik.frontend.rule (die URL, auf dem der Service hören soll)
  • traefik.port (der Port, auf dem eure Anwendung hört)

Der Rest kann jeweils übernommen werden. Sollte ihr euren Container schon gestartet haben, solltet ihr diesen beenden, evtl. den Container löschen und neu starten. Ein paar Sekunden später ist der Service dann extern verfügbar.

26 Kommentare

  1. Vielen Dank für den Artikel und das Video. Kann mir vorstellen, dass das Ganze zu machen ziemlich aufwendig ist. Lustigerweise machst du die ganzen Dinge, dich ich auf meiner Homelab-To-Do-Liste gesammelt habe. Leider fehlt mir aktuell die Zeit für die Abarbeitung.

    • Das freut mich zu hören!

      Der YouTube Kanal ist ja genau aus der Motivation heraus entstanden anderen Leuten bei ihren Vorhaben zu unterstützen. Ich merke es ja immer selbst, dass ich das einfuchsen in verschiedene Themen nicht immer so leicht ist. Da ist es ein Vorteil wenn es jemand einigermaßen verständlich erklärt.

  2. Vielen Dank für Deine hilfreichen Videos und Blogbeiträge.
    Zum Thema „Reverse Proxy mit Traefik“ würde mich noch interessieren wie ich Traefik zusammen mit „Non-Docker“ Services nutzen kann? Welche Einstellungen muss ich in Traefik vornehmen um sowohl Services die in Docker Containern laufen als auch Services die nicht in Docker Containern laufen aus dem Internet aufzurufen?

    • Komplett ohne Docker wäre Traefik etwas sinnfrei, weil seine Stärken einfach bei Containern liegen. Wenn man aber einen Mischbetrieb nutzen möchte, muss man für Nicht-Docker-Services einzelne Backends definieren. Hier bei Reddit ist ein Beispiel.

  3. hi,
    ich habe deine vorlage exakt befolgt (domain/email angepasst), bekomme aber nur ein:

    404 page not found

    wenn ich traefik im browser aufrufen möchte.

    portainer-oberfläche komme ich rauf.

    vg hardy

    • Also 100 %ig exakt wäre nicht gut, weil dir sicherlich nicht die Domain example.com gehört. Ich gehe aber mal davon aus, dass du das angepasst hast?
      Docker Container hast du mit den environment variables auch richtig angepasst? Port etc richtig angegeben?

  4. ok – bin nun im traefik-dashboard 🙂
    hab eine andere proxmox-bridge genommen. (vmbr0 statt vmbr1) – muss mal gucken was ich da in opnsense noch ändern muss…

    dann mache ich mal weiter 🙂

    vg hardy

  5. ich hab da noch n paar fragen:
    habe auf meinem strato-vserver eine subdomian „whoami.domain.de“ angelegt.
    habe eine c-name-weiterleitung eingerichtet.
    auf welche ip muss ich zuhause die weiterleitung einrichten? auf die docker-vm oder auf die traefik-ip incl. portnummer?

    gruss hardy

    • Auf die Docker VM. Traefik sollte hier auf Port 80 und 443 exklusiv lauschen. Traefik übernimmt dann das routing auf andere Webanwendungen.

  6. habe die weiterleitung http und https auf die ip der docker-vm eingerichtet.
    portainer zeigt dies an:

    traefik /running /traefik/traefik:latest/2019-04-29 16:20:18/172.21.0.3/443:443 80:80 8080:8080

    whoami-1/running/traefik/jwilder/whoami/2019-04-29 16:20:18/172.21.0.2 –

    portainer/running/- portainer/portainer/2019-04-03 09:10:14/172.17.0.2/9000:9000

    wenn ich im browser whoami.meinedomain.de eingebe, ist die seite nicht erreichbar.
    hast du noch n tipp?
    und wie richtet man ein passwort für traefik ein? bin kompletter docker-anfänger…:-)
    kann ich dir scrennshots an deine mailadresse senden?

    vg hardy

  7. Hi Teqqy,

    ich hätte eine Frage dazu, vielleicht kennst du die Lösung schon.
    Von Extern funktioniert das alles bereits bestens, mir geht es darum die Dienste auch intern über meine Domain ansprechen zu können. Über „traefik.enable=true“ lege ich ja grundsätzlich fest ob Traefik den Service propagiert, egal von wo die Anfrage kommt (wenn ich es richtig verstanden habe). Mein Ziel wäre z.B. das ich nextcloud.meinedomain.de von innen und außen erreiche (das funktioniert ja bereits wunderbar) und portainer.meinedomain.de nur aus meinem lokalen Netzwerk. Bisher muss ich für lokale Dienste weiterhin mit IP+Port arbeiten.

  8. Danke für die tolle Anleitung! Leider sind die Ports 80, 443 und 8080 laut Docker Synology belegt…..

    Im Netzwerk sind neben einem UniFi Controller noch ein Pi-Hole und Loxberry. Was genau kann ich tun, damit ich den Reverse Proxy zum Laufen bekomme?

    • Da musst du die Ports von der Synology verändern. Mit Traefik 2.0 kann man auch andere Ports als 80 und 443 verwenden, allerdings habe ich mich damit noch nicht befasst.

    • Jan Amundsen

      Das Problem hatte ich auch.
      Hiermit lässt sich das beheben:
      #!/bin/sh
      sed -i -e ’s/80/81/‘ -e ’s/443/444/‘ /usr/syno/share/nginx/server.mustache /usr/syno/share/nginx/DSM.mustache /usr/syno/share/nginx/WWWService.mustache
      synoservicecfg –restart nginx

      Damit schreibst du die Ports 80 und 443 für eine Synology-Dienste auf 81 und 444 um.

      Danach lassen sich die Ports im Docker benutzen.

      Ich stolpere in der Anleitung allerdings auch noch über einige Dinge.
      Wenn ich es so mache wie hier beschrieben, erstellt Docker immer zwei Netze: traefik_proxy und traefik_default

      $ sudo docker compose up
      Creating network „traefik_default“ with driver „bridge“
      Creating traefik … error
      Creating whoami-1 …

      ERROR: for traefik Cannot start service traefik: driver failed programming external connectivity on endpoint traefik (1ef012cd8589c59f49608d8a4502029d9211b34a622956908c84359a39eb9f37): Error starting userland proxy: listen tcp 0.0.0.0:80Creating whoami-1 … done

      ERROR: for traefik Cannot start service traefik: driver failed programming external connectivity on endpoint traefik (1ef012cd8589c59f49608d8a4502029d9211b34a622956908c84359a39eb9f37): Error starting userland proxy: listen tcp 0.0.0.0:8080: bind: address already in use
      ERROR: Encountered errors while bringing up the project.

      Ich verzweifel langsam an dem ollen Reverse Proxy. Ich habe nur vier halbwegs anständige Anleitungen gefunden, von denen keine bei mir funktioniert 🙁
      Ich hab den Docker auf ner Synology laufen.

      Kann mir noch jemand helfen?

      • Sebastian

        Hallo Jan,
        leider bekomme ich die Ports 80 und 443 von meiner DS918+ nicht um gebogen.
        Script:

        #!/bin/sh
        sed -i -e ’s/80/81/‘ -e ’s/443/444/‘ /usr/syno/share/nginx/server.mustache /usr/syno/share/nginx/DSM.mustache /usr/syno/share/nginx/WWWService.mustache

        danach
        synoservicecfg –restart nginx

        Docker Compose meldet.

        Error starting userland proxy: listen tcp 0.0.0.0:443: bind: address already in use

        Hast du evtl. noch eine Idee ? Aktuellste DSM ist installiert

  9. Hallo, danke für deine Tutorials, haben mir echt weitergeholfen grundlegend traefik zu verstehen. Ich hab nur eine Frage was muss ich alles umkonfigurieren wenn ich anstatt der acme also lets encrypt, mein eigenes Wildcard cert/Key verwenden will in der toml und der ymal? Wohin soll ich die Key/cert Files mounten -v ./certs:/etc/certs ? Irgendwie krieg ich das in der toml nicht hin das er mir diese
    Key/cert dafür verwendet.

  10. Hallo Christian, erstmal ein tolles Lob an Deine Tutorials. Schaue ich mir gerne an und versuche manche Dinge eigenständig umzusetzen. Leider scheitere ich schon ein paar Tage an dem Docker Container Traefik. Bei mir erscheint immer „404 Page not found“ Könntest Du ggf. unterstützten? Vorab vielen Dank!

    • Hallo Marty,
      schreib mir doch bitte mal ne Email mit den Informationen. Am besten welche compose Datei du verwendet und evtl. auch mal ein Auszug aus dem traefik log. Dann kann ich dir sicherlich weiter helfen.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.