Mit Docker lassen sich sehr leicht neue Container auf einem Host erstellen. Sollen aber mehrere Container über dem Port 80 (HTTP) nach außen kommunizieren, so kann es etwas problematisch werden, da dieser Port nur einmal auf dem Server zur Verfügung steht.

Hier kann ein Reverse Proxy Abhilfe schaffen. Ein bekanntes Spiel ist Traefik.

Ich habe diese Anleitung erstellt, da die meisten Anleitungen im Netz leider nicht mehr funktionieren (Traefik v1) und es kaum aktuelle Anleitungen gibt.

Update

07.05.2020Kapitel zur Docker Installation hinzugefügt.
27.03.2020Erstellung dieser Anleitung.

Meine Anleitung bezieht sich auf die aktuelle Traefik Version 2. Dies ist wichtig, da die Konfigurationen bei Version 1 anders sind.

0. Was ist das Ziel dieser Anleitung?

  • Traefik v2 installieren
  • TLS aktivieren
  • Automatisch gültige Zertifikate von Let´s encrypt zu beziehen
  • Wissen, wie ihr neue Anwendungen zu Traefik hinzufügt.

1. Installation von Docker und Docker Compose

Nun installieren wir zuerst Docker & Docker Compose. Diese beiden Programme bilden die Grundlage.

1.1 Docker installieren

Zur Installation von Docker habe ich hier eine Anleitung geschrieben.

1.2 Docker Compose installieren

Docker Compose könnt ihr mit wenigen Zeilen Code installieren.

sudo apt-get update
sudo apt-get install curl
sudo curl -L "https://github.com/docker/compose/releases/download/1.25.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

Anschließend müsst ihr nur noch die Berechtigung anpassen.

sudo chmod +x /usr/local/bin/docker-compose

Nun könnt ihr testen, ob Docker Compose richtig installiert ist.

root@xxx:/# docker-compose version
docker-compose version 1.25.4, build 8d51620a
docker-py version: 4.1.0
CPython version: 3.7.5
OpenSSL version: OpenSSL 1.1.0l  10 Sep 2019

Eine ausführlichere Anleitung findet ihr direkt hier beim Hersteller.

2. htpasswd installieren

Wir installieren nun noch das Tool htpasswd. Dieses benötigen wir um uns ein Passwort für Traefik zu generieren.

apt-get update
apt-get install apache2-utils

3. Traefik installieren und konfigurieren

3.1 Verzeichnisse / Dateien anlegen

Als erstes legen wir uns ein Verzeichnis für Traefik an. Ich wähle dazu folgendes:

mkdir -p /opt/containers/traefik

Anschließend erzeugen wir uns noch ein paar Datein / Ordner, welche wir später noch benötigen.

mkdir -p /opt/containers/traefik/data
touch /opt/containers/traefik/data/acme.json
chmod 600 /opt/containers/traefik/data/acme.json
touch /opt/containers/traefik/data/traefik.yml

3.2 traefik.yml anpassen

Nun bearbeiten wir die Datei „traefik.yml“. Dabei ist wichtig, dass ihr nur Leerzeichen und keine Tabs benutzen dürft.

nano /opt/containers/traefik/data/traefik.yml

Inhalt:

api:
  dashboard: true

entryPoints:
  http:
    address: ":80"
  https:
    address: ":443"

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false

certificatesResolvers:
  http:
    acme:
      email: email@example.com   #### hier eure E-Mail angeben ####
      storage: acme.json
      httpChallenge:
        entryPoint: http

Im Code müsst ihr noch eure E-Mail angeben. Ohne Anführungszeichen oder sonstigem.

3.3 docker-compose.yml anpassen

Nun legen wir unsere Docker Compose Datei an.

nano /opt/containers/traefik/docker-compose.yml

Inhalt:

version: '3'

services:
  traefik:
    image: traefik:latest
    container_name: traefik
    restart: unless-stopped
    security_opt:
      - no-new-privileges:true
    networks:
      - proxy
    ports:
      - 80:80
      - 443:443
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./data/traefik.yml:/traefik.yml:ro
      - ./data/acme.json:/acme.json
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.traefik.entrypoints=http"
      - "traefik.http.routers.traefik.rule=Host(`traefik.example.com`)"
      - "traefik.http.middlewares.traefik-auth.basicauth.users=USER:PASSWORD"
      - "traefik.http.middlewares.traefik-https-redirect.redirectscheme.scheme=https"
      - "traefik.http.routers.traefik.middlewares=traefik-https-redirect"
      - "traefik.http.routers.traefik-secure.entrypoints=https"
      - "traefik.http.routers.traefik-secure.rule=Host(`traefik.example.com`)"
      - "traefik.http.routers.traefik-secure.middlewares=traefik-auth"
      - "traefik.http.routers.traefik-secure.tls=true"
      - "traefik.http.routers.traefik-secure.tls.certresolver=http"
      - "traefik.http.routers.traefik-secure.service=api@internal"

networks:
  proxy:
    external: true

Notwendige Anpassungen:

  • Hostnamen anpassen: Hier müsst ihr noch die Zeilen mit eurem Hostnamen (traefik.example.com) anpassen.
  • Benutzer / Passwort festlegen: Ihr müsst noch euer Passwort / Benutzer festlegen. Hier in diesem Beispiel werden folgende Daten festgelegt.
  • Benutzer: user
  • Passwort: password

Ändert also bitte die nächste Code-Zeile entsprechend euren Wünschen ab. Dazu gebt ihr folgendes ein eure Shell ein:

echo $(htpasswd -nb user password) | sed -e s/\\$/\\$\\$/g

Ausgabe: user:$$apr1$$7ciH.Uzt$$DUqDgmpLmFE2Fm7Z7VaMe/

Der Befehl wird hier beim Hersteller erklärt. Diese Zeichenkette kopiert ihr nun in eure Konfiguration:

vorher:
"traefik.http.middlewares.traefik-auth.basicauth.users=USER:PASSWORD"

nachher:
"traefik.http.middlewares.traefik-auth.basicauth.users=user:$$apr1$$7ciH.Uzt$$DUqDgmpLmFE2Fm7Z7VaMe/"

3.4 Docker Netzwerk anlegen

Als nächstes müssen wir noch ein internes Netzwerk anlegen, über welches später unsere Docker Container mit Traefik kommunizieren sollen. Dies haben wir in unserer Compose Datei „proxy“ genannt.

docker network create proxy

4. Traefik starten

Nun können wir Traefik starten.

docker-compose -f /opt/containers/traefik/docker-compose.yml up -d

Wenn ihr nun auf traefik.euredomain.de geht, solltet ihr folgendes sehen:

Nach dem Login mit eurem oben festgelegten Passwort solltet ihr diese Übersicht sehen.

Hier sind wir jetzt fertig mit der Traefik Konfiguration und Installation.

5. Anwendungen anlegen am Beispiel von WordPress

Hier zeige ich euch am Beispiel von WordPress, wie ihr neue Anwendungen hinzufügen könnt.

Dazu legen wir uns neue Ordner an:

mkdir -p /opt/containers/wordpress/{db-daten,wp-daten}

Nun erstellen wir unsere Docker Compose Datei.

nano /opt/containers/wordpress/docker-compose.yml

Inhalt:

version: '3'

services:
   db:
     image: mariadb:latest
     volumes:
       - /opt/containers/wordpress/db-daten:/var/lib/mysql
     environment:
       MYSQL_ROOT_PASSWORD: geheim <--- – SQL Passwort – -->
     networks:
       - default
     restart: unless-stopped

   wp:
     image: wordpress:latest
     volumes:
       - /opt/containers/wordpress/wp-daten:/var/www/html

     labels:
      - "traefik.enable=true"
      - "traefik.http.routers.wp.entrypoints=http"
      - "traefik.http.routers.wp.rule=Host(`wordpress.euredomain.de`)"
      - "traefik.http.middlewares.wp-https-redirect.redirectscheme.scheme=https"
      - "traefik.http.routers.wp.middlewares=wp-https-redirect"
      - "traefik.http.routers.wp-secure.entrypoints=https"
      - "traefik.http.routers.wp-secure.rule=Host(`wordpress.euredomain.de`)"
      - "traefik.http.routers.wp-secure.tls=true"
      - "traefik.http.routers.wp-secure.tls.certresolver=http"
      - "traefik.http.routers.wp-secure.service=wp"
      - "traefik.http.services.wp.loadbalancer.server.port=80"
      - "traefik.docker.network=proxy"

     networks:
       - default
       - proxy
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_PASSWORD: geheim  <-- – SQL Passwort – -->
     restart: unless-stopped

networks:
  proxy:
    external: true

Notwendige Änderungen:

  1. Die zwei Zeilen mit den SQL Passwörtern müsst ihr ändern.
  2. Die zwei Zeilen mit euer Domain (wordpress.euredomain.de) müsst ihr anpassen.

Nun können wir WordPress starten.

docker-compose -f /opt/containers/wordpress/docker-compose.yml up -d

Wenn ihr jetzt auf “ wordpress.euredomain.de“ geht, sollte es so aussehen:

Unter Traefik solltet ihr nun sehen, dass es mehr „Routers“ gibt.

Ein Klick auf „explore“ zeigt euch eine Übersicht und da sollte „wordpress.euredomain.de“ auftauchen.

6. Wie kann ich Anwendungen im Allgemeinen zu Traefik hinzufügen?

Im Allgemeinen ist es wichtig, dass ihr die Labels hinzufügt.

   wp:
     labels:
      - "traefik.enable=true"
      - "traefik.http.routers.wp.entrypoints=http"
      - "traefik.http.routers.wp.rule=Host(`wordpress.euredomain.de`)"
      - "traefik.http.middlewares.wp-https-redirect.redirectscheme.scheme=https"
      - "traefik.http.routers.wp.middlewares=wp-https-redirect"
      - "traefik.http.routers.wp-secure.entrypoints=https"
      - "traefik.http.routers.wp-secure.rule=Host(`wordpress.euredomain.de`)"
      - "traefik.http.routers.wp-secure.tls=true"
      - "traefik.http.routers.wp-secure.tls.certresolver=http"
      - "traefik.http.routers.wp-secure.service=wp"
      - "traefik.http.services.wp.loadbalancer.server.port=80"
      - "traefik.docker.network=proxy"

Wichtig ist hier auch, dass unser Service „wp“ heißt und dementsprechend die Labels auch alle auf den Namen „wp“ angepasst werden müssen. Dies kann aber auch jeder andere Name sein. Muss nur konstant sein.

Ihr müsst immer noch das Netzwerk hinzufügen, mit dem Traefik kommuniziert. Dieses Netzwerk ist im einfachsten Fall bei jeder Anwendung identisch. In diesem Fall also „proxy“.

   wp:
     networks:
       - proxy

networks:
  proxy:
    external: true

Der Name „proxy“ wurde hier auch frei gewählt. Dort könnt ihr auch jeden anderen Namen verwenden. Wichtig hierbei ist jedoch, dass das Netzwerk unter Docker angelegt ist:

docker network create NamedesNetzwerks

Damit alle Anleitungen hier auf der Homepage bei euch funktionieren, MÜSST ihr den nachfolgenden Punkt 7 noch durchführen!

7. TLS Sicherheit verbessern

Standardmäßig ist Traefik laut SSL Labs nicht so sicher. Hier zeige ich euch, wie ihr dies schnell verbessern könnt.

Ich empfehle jedem diesen Anleitung auch noch zu machen, damit ihr die anderen Anleitungen hier auf meiner Seite 1:1 kopieren könnt. Sonst müsst ihr immer Anpassungen bezüglich der Sicherheit vornehmen.

Dies habe ich hier ausgegliedert, damit diese Anleitung „schlank“ bleibt.

8. Quellen

https://docs.traefik.io/

https://medium.com/@containeroo/traefik-2-0-docker-a-simple-step-by-step-guide-e0be0c17cfa5

https://hub.docker.com/_/traefik

Teile diesen Beitrag
Christian

Categories:

35 Kommentare

  1. Hi,

    sehr gut beschrieben, hat auf Anhieb geklappt.
    Aber wie bringe ich es fertig das ich das Dashboard nur aus dem lokalen Netz erreiche?
    Docker läuft bei mir im heimischen Netzt und nicht auf einem Root-Server.

  2. Moin,
    vermutlich bin ich einfach nur zu Doof, aber ich bekomme das Traefik nicht zum laufen. Mehr gesagt, es läuft aber ich kann mich nicht ein loggen.
    Ich hänge immer in der Anmeldemaske fest.

    Gruß

    • Ich hatte ein ähnliches Problem und bin an der Anmeldemaske nicht weitergekommen, weil ich einfach user und password hatte im Befehel stehen lassen und dann gewundert, dass das, was dabei rauskommt, nicht als Passwort funktioniert: echo $(htpasswd -nb user password) | sed -e s/\\$/\\$\\$/g

      10 min später dämmerte es mir, dass ich damit ja als Login „user“ und „password“ festgelegt habe, fasste mir an den Kopf und habe user und password durch eine eigene Eingabe ersetzt (in meinem Passwortmanager hinterlegt) und den Output des Kommandos, wie in der Anleitung beschrieben, in der docker-compose.yml eingepflegt.

      • Danke für die Antwort, aber den Schritt „echo $(htpasswd -nb user password) | sed -e s/\\$/\\$\\$/g“ habe ich auch gemacht und auch das in die dementsprechende Zeile eingefügt. Zudem habe ich auch die Domain eingetragen.

        Der jetzige Fehler ist 404 Seite nicht gefunden.

        Ich verstehe das bald alles nicht mehr.

        • So den Fehler 404 habe ich hin bekommen. habe einfach dei der einen Domain die Endung .de vergessen 🙂
          Nur die Anmeldung funktioniert leider immer noch nicht.

          Den Befehl „echo $(htpasswd -nb user password) | sed -e s/\\$/\\$\\$/g“ habe ich ausgeführt sonst funktioniert die Anwenung nicht. Habe aber dann die Zeile wo das Passowrd und der Anwender steht gegen ein anderes Passwort geändert. Leider funktioniert es immer noch nicht.

          Selbst wenn ich die Zeile soausfülle – „traefik.http.middlewares.traefik-auth.basicauth.users=user:password“ hänge ich in einer dauer Anmeldeschleife.

          • Hallo Olaf,
            ich habe das Kapitel 3.3 etwas umgeschrieben, damit es vlt deutlicher wird. Aber in die Konfig wird KEIN Benutzername / Passwort im Klartext geschrieben.

            LG
            Christian

  3. Hallo Christian,

    danke für die Info. Jetzt wird auch ein Schuh draus.
    Ach noch was. Wenn ich hier ein Kommentar eintrage, kommt folgende Fehlermeldung :

    Error: You have entered an incorrect reCAPTCHA value.
    Click the BACK button on your browser and try again.

    Gruß

  4. Hallo,

    Das sind schon wirklich sehr gute Anleitungen. Danke dafür.
    Ich bekomme bei Nextcloud und Grafana im Moment leider jeweils folgenden Fehler per Traefik:

    middleware „secHeaders@file“ does not exist

    Die Einträge wie (hier bei NC)

    – „traefik.http.routers.nextcloud-app-secure.middlewares=nextcloud-dav,secHeaders@file“

    sind jeweils vorhanden.
    Kann es sich um ein Problem bei den User-Rechten handeln?
    Welchem User sollten die yml-Files denn in der Praxis zugeordnet sein und als welcher User starte ich am besten docker-compose?

    Grüsse

      • Hallo,

        Habe den Fehler gefunden ..

        file:
        filename: „/dynamic_conf.yml“ in traefik.yml vergessen hinzuzufügen ….

        Nun schnurrt alles. 🙂

        Danke nochmal für die sehr guten Anleitungen.
        Beim Nextcloud werde ich noch Redis Support hinzufügen und ggf. andere Optimierungen vornehmen.

        Grüsse

  5. Hey ho, habe dies nun 2x Probiert

    Ich habe alles mehrmals überprüft

    Bleibe aber immer bei „4. Traefik starten“ stehen da ich einen „521: Web server is down“ fehler bekomme

    ich weis gerade nicht an was es liegt, falls jemand von euch es weis gebt mir gerne bescheid, ich suche fürs erste mal eine andere anleitung

    • Hallo,
      versuch mal beim Schritt 4 folgenden Befehl (also ohne -d)
      docker-compose -f /opt/containers/traefik/docker-compose.yml up

      So müsstest du die Ausgabe auf deiner Console sehen und somit auch das genaue Problem / Fehler.

      LG
      Christian

  6. Hallo!

    Ich habe die Anleitung durchgearbeitet und mehrfach die Schritte überprüft. Die Seite geht im Browser nicht auf. Traefik läuft, die Umleitung von http zu https funktioniert, aber es kommt im Browser der Fehler: ERR_SSL_PROTOCOL_ERROR

    Was mache ich falsch?

    Danke!!
    Tom

    • Irgendetwas scheint beim Abholen des Zertifikats nicht geklappt zu haben. Ich habe den Redirect herausgenommen und anschließend nochmal gestartet, und siehe da, es klappt jetzt! Vielleicht hilft die Info auch noch jemand anderem.

  7. Beim Ausführen von:
    sudo docker-compose -f /opt/containers/traefik/docker-compose.yml up -d

    erhalte ich folgenden Fehler:

    ERROR: In file ‚/opt/containers/traefik/docker-compose.yml‘, service must be a mapping, not a NoneType.

    Ich habe docker-compose.yml so erzeugt wie in der Anleitung angegeben. Wie kann ich den Fehler beheben?

  8. Hallo Christian,
    vielen Dank für die sehr ausführliche Anleitung und danke, dass du dein Know-how teilst.
    Ich freue mich auf weitere spannende Projekte von dir.

    Vielen Dank und viele Grüße,
    Koray

  9. Hallo Christian, ganz herzlichen Dank für die Tutorials. Sie sind sehr wertvoll. Da ich gerne weiß, was ich tu … könntest du den mechnismus mit den Labels etwas erklären? Leider finde ich kaum Dokumentation, wie in einem Container die labels ausgelesen werden können. Ich verstehe das so.

    1. Traefik liest von den laufenden Containern die labels aus um fesztzustellen, ob ein container für traefik relevant ist. („traefik.enable=true“). Dazu verwendet es die docker-api unter unix:///var/run/docker.sock
    2. traefik konstruiert einen Key nach dem Muster traefik.{funktion}.{containername.{funktionsparameter}. Auf diese Weise ist es möglichk, traefik an den „Ziel“ – containern zu konfigurieren

  10. Hallo Christian,
    herzlichen Dank für das anschauliche Tutorial.
    Dazu habe ich einige Fragen: Unter welchem User führe ich denn die Befehle ab Kap. 3.1 aus? Als root? Oder als einfacher User? Brauchen die Dateien dementsprechend spezielle Rechte?

    Danke Dir für eine kurze Erläuterung.

    Herzliche Grüße
    Gerrit

  11. Hallo Christian,

    auch ich darf dir ein großes Danke hier lassen!

    Alles hat geklappt bis auf das ändern von Punk „3.3 docker-compose.yml anpassen“.
    Der Zugang über die subdomain traefik.meinedomain.de klappt lediglich mit user/password – ein neustart von docker/docker-compose sowie ein löschen er alten images hat nichts bewirkt. Ich weiß nicht ob das damit zusammenhängt das mit der zweiten Anleitung „https://goneuland.de/traefik-v2-https-verschluesselung-sicherheit-verbessern/“ auch keine Effekte eintreten..

    Bin für jede Hilfe dankbar.

    Liebe Grüße Omar

  12. Hallo,

    Danke für die Tutorials.

    Was mir so ein bisschen sorgen macht ist die tatsache, das alle services als user root laufen.
    es gibt da wohl die möglichkeit mittels user: 1000:1000 bzw user: username das zu ändern,
    allerdings will es mir nicht gelingen, die container starten einfach nicht ( restarting )

    wäre super wenn du das evtl anpassen könntest, der sicherheit wegen 🙂

    mfg
    Thomas

    • Hallo Thomas,
      ja es ist möglich, dass man in den Containern eigene Benutzer anlegt, welche dann die Anwendungen starten.
      Einige der Container machen dies „automatisch“.

      Ich habe meine Anleitungen hier sehr „einfach“ gehalten und daher gehe ich hier auf solche Aspekte weniger ein.

      LG
      Christian

  13. Hallo 🙂

    bei mir erscheint beim Start folgende Fehlermeldung.
    root@v16015:/opt/containers/traefik# ERROR: for traefik Cannot start service traefik: driver failed programming external connectivity on endpoint traefik (75f3d202c2e22691039cd713a577ad0fe8fd4bde9d7bb3d1f581041405f5c5be): Error starting userland proxy: listen tcp 0.0.0.0:443: bind: address already in use
    -bash: syntax error near unexpected token `(‚

    Ich denke es hat was mit den Ports zu tun. Finde aber keine Lösung.

    Weiss Du oder jemand hier vielleicht eine Lösung ?

  14. Hallo 🙂

    das Port Problem ist gelöst aber dann erscheint beim Aufruf der Webseite folgendes:

    Datenschutzfehler

    Ihre Verbindung ist nicht privat.
    Angreifer versuchen möglicherweise Ihre Informationen von traefik.marcos-cloud.de zu stehlen (z. B. Kennwörter, Nachrichten oder Kreditkarten).
    NET::ERR_CERT_AUTHORITY_INVALID

    Die Seite ist mit einem LetsEncrypt Zertifikat geschützt.

    Im Log des Containers steht folgendes:

    time=“2020-08-01T19:32:50+02:00″ level=error msg=“error parsing BasicUser: USER::$apr1$EWQVnN0K$8P8qBkiNHWIn3SCdqahJW/“ entryPointName=https routerName=traefik-secure@docker
    time=“2020-08-01T19:32:58+02:00″ level=error msg=“Unable to obtain ACME certificate for domains \“marcos-cloud.de\“: unable to generate a certificate for the domains [marcos-cloud.de]: error: one or more domains had a problem:\n[marcos-cloud.de] acme: error: 403 :: urn:ietf:params:acme:error:unauthorized :: Invalid response from https://marcos-cloud.de/.well-known/acme-challenge/LwQQJxI9lVjrWuJeV1LkTJ8XVYAlzKP6Pjyh1pi4m7I [178.254.9.9]: \“\\r\\n404 Not Found\\r\\n\\r\\n404 Not Found\\r\\nnginx\\r\\n\“, url: \n“ routerName=traefik-secure@docker rule=“Host(`marcos-cloud.de`)“ providerName=http.acme

    Weiss jemand Rat ?

    Vielen Dank 🙂

  15. Du hast hier einige top HowTos publiziert die mri sehr geholfen haben. Ich habe eben einen kleinen Hinweis in den Logs entdeckt den du korrigieren könntest.

    dockerd[2108]: time=“2020-08-07T09:51:33.715401963+02:00″ level=warning msg=“Security options with `:` as a separator are deprecated
    and will be completely unsupported in 17.04, use `=` instead.“

    I schätze mal das sollte dann so aussehen?

    security_opt:
    – no-new-privileges=true

  16. Hallo Christian, danke für deine Anleitung / Anleitungen, super.

    Folgende Fragen zu dieser:

    Warum verwendest Du root und sudo im Tutorial abwechselnd, hat das eine Grund oder übersehen?
    Warum USER (/opt/containers/traefik/docker-compose.yml) und „user“ in der Beschreibung von Traefik, hat es einen Grund?

    Funktioniert, sollte deine Anleitung auch mit einer kostenfreien Subdomain funktionieren?

    Viele Grüße
    Matthias

Schreibe einen Kommentar

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