Reverse Proxy mit Traefik unter Docker

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.

34 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.

  11. Hallo Christian,
    vielen Dank für deine super Anleitung!
    Kannst du mir bitte sagen, ob es möglich ist nur bestimmte Dienste über traefik ins Internet zu bringen und andere nicht?
    Hintergrund ist, dass ich zb Nextcloud von Außen erreichen möchte aber zb. mein ungesichertes Grafana oder Wiki nicht. Ich möchte aber alle Dienste über eigene Subdomains und https ansprechen können. Prinzipiell läuft das bei mir auch schon nur eben ohne Internet.

    • Du bestimmst immer selbst welche Services über Traefik laufen und welche nicht. Fügst du die Konfiguration hinzu wird es veröffentlicht, sonst nicht.
      Traefik kann, stand jetzt, aber nur HTTP/HTTPS, also kein Email oder ähnliche Services.

  12. Hallo teddy
    kannst mir mir mal sagen wo ich den gesamten Ordner docker-homelab-master hochlade in welches Verzeichnis,
    muss ich den umbenennen in docker kommt alles in var oder nur ein teil
    muss ich noch was wo anders kopieren

    anfänger Vorab vielen Dank!

  13. Christoph

    Hallo Christian,
    auch ich bin begeistert, wie du die komplexen Sachverhalte anschaulich und nachvollziehbar erklärst.
    Leider komme ich auf meiner QNAP nicht wirklich weiter. Das anfängliche Portproblem konnte ich lösen, da diese noch von der „alten“ Datenbank und PHP -Instanz belegt waren.
    Jetzt bekomme ich die Meldung:
    level=info msg=“Configuration loaded from file: /etc/traefik/traefik.toml
    Wo eigentlich gar nichts ist?!
    Diese sollte doch mit dem Eintrag in der docker-compose.yaml:
    volumes:

    – $PWD/config:/etc/traefik

    richtig zu finden sein.
    Schonmal danke für die Hilfe!

  14. Hallo teddy,

    vielleicht kannst du mir auch weiter helfen, ich versuche mich auch nun an Treafik und Letsencypt. Auf meinem Servern sieht soweit auch alles gut aus. Jedoch haben die Zertifikate keine gültigkeit. Ich habe im Web gelesen das ich bei STrato, der meien Domain hostet ein TXT eintrag vornehmen muss (_acme-challenge.sub.example.com) jedoch scheitere ich daran, das ich nicht weiß welchen Wert ich dort eintragen kann. Hast du da eine idee ?

    Bei welchen Hoster bist du ? vielleicht sollte ich mal wechseln 🙂

    Gruß
    Marhal

    • Das kommt immer darauf an wie Traefik die Zertifikate ziehen soll. Wenn dein Hoster das nicht unterstützt kannst du unter anderem auch auf HTTP01 umstellen. Dann überprüft er nicht DNS sondern nur sich selbst. Ist aber unsicherer, weil dann quasi jeder daher kommen kann und kann Zertifikate für deine Domain ausstellen.

      Ich hoste meine Domains bei Netcup, DNS allerdings bei Cloudflare. Die haben, wie viele andere, ne API mit dem Traefik bzw. Lets Encrypt kommunizieren kann.

  15. Marco Meyerer

    Vielen Danke für dein Tut.

    jedoch habe ich beim starten ein Problem.

    ERROR: for traefik Cannot start service traefik: driver failed programming external connectivity on endpoint traefik (4810f0be27c4d58308c8e755dcab43b28233820defc9ac0db5121e1148738130): Error starting userland proxy: listen tcp 0.0.0.0:443: bind: address already in use

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

    ich hab gesehen, gab schon welche die hatten ähnliche Probleme.

    ich hab geschaut in meine Docker läuft aktuell kein Container, das heißt der port 443 wird nicht verwendet von docker/container.

    jedoch mit netstat -tulpn | grep LISTEN sehe ich

    tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 10218/nginx: worker

    muss ich den beenden?

Schreibe einen Kommentar

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