Docker: HTTPS-Routing

Wie man HTTP-Routing und TLS-Verschlüsselung (HTTPS) in Docker-Containern verwaltet

👋 Willkommen in der Stackhero-Dokumentation!

Stackhero bietet eine einsatzbereite Docker Cloud CaaS (Containers as a Service) Lösung, die zahlreiche Vorteile bietet, darunter:

  • Einfache Bereitstellung Ihrer Container in der Produktion mit nur einem docker-compose up.
  • Anpassbarer Domainname gesichert mit HTTPS (zum Beispiel, https://api.ihre-firma.com, https://www.ihre-firma.com, https://backoffice.ihre-firma.com).
  • Optimale Leistung und robuste Sicherheit durch eine private und dedizierte VM.
  • Mühelose Updates mit nur einem Klick.

Sparen Sie Zeit und vereinfachen Sie Ihr Leben: Es dauert nur 5 Minuten, um die Docker CaaS Cloud Hosting Lösung von Stackhero auszuprobieren und Ihre Container in der Produktion bereitzustellen!

Jede Stackhero for Docker-Instanz enthält einen dedizierten, vorkonfigurierten Traefik-Server, der den HTTP-Verkehr verwaltet und automatisch mit TLS-Zertifikaten verschlüsselt. Diese optimierte Einrichtung macht das Routing einfach und effizient. Zum Beispiel:

  • Leiten Sie den Verkehr von https://www.my-company.com (mit oder ohne www-Präfix) zu Ihrem frontend-Container.
  • Routen Sie https://www.my-company.com/documentations zu Ihrem documentations-Container.
  • Leiten Sie https://api.my-project.io zu Ihrem api-Container.

Sie können eine unbegrenzte Anzahl von Domains mit automatischer Erstellung und Erneuerung von TLS-Zertifikaten verwalten. Das Beste daran ist, dass Sie all dies mit nur drei Zeilen konfigurieren können!

In allen folgenden Konfigurationsbeispielen müssen Sie <XXXXXX>.stackhero-network.com durch Ihren Stackhero for Docker-Instanz-Domainnamen ersetzen.

Unten ist ein einfaches Beispiel für eine docker-compose.yml-Datei:

services:
  test:
    image: nginx
    labels:
      - "traefik.enable=true" # Aktivieren Sie Traefik, um den Verkehr zu diesem Container zu leiten
      - "traefik.http.routers.test.rule=Host(`<XXXXXX>.stackhero-network.com`)" # Definieren Sie den Host
      - "traefik.http.routers.test.tls.certresolver=letsencrypt" # Verwenden Sie 'letsencrypt' als TLS-Zertifikatsresolver

In diesem Beispiel läuft ein Container namens test mit dem Nginx-Image. Die Schlüsselkonfiguration wird im Abschnitt Labels bereitgestellt. Sie müssen diese Zeilen einfach in Ihre docker-compose.yml-Datei kopieren und <XXXXXX>.stackhero-network.com durch Ihre Dienst-Domain ersetzen.

Sie können den Container mit folgendem Befehl bereitstellen:

docker context use <XXXXXX>.stackhero-network.com
docker-compose up

Nach dem Start des Containers besuchen Sie https://<XXXXXX>.stackhero-network.com/, um die "Welcome to nginx!"-Seite zu sehen.

Nginx-WillkommensseiteNginx-Willkommensseite

Wenn Sie die Nginx-Willkommensseite nicht sehen, überprüfen Sie das Traefik-Dashboard auf mögliche Fehler!

Mit dieser Konfiguration werden HTTP-Anfragen an <XXXXXX>.stackhero-network.com zu Ihrem test-Container geleitet und Traefik erstellt und verwaltet automatisch TLS-Zertifikate für HTTPS.

Im vorherigen Beispiel haben wir die Standard-Domain <XXXXXX>.stackhero-network.com verwendet. In der Praxis werden Sie wahrscheinlich Ihre eigenen Unternehmens- oder Projektdomains verwenden, wie www.my-company.com oder api.my-project.io. Der folgende Abschnitt erklärt, wie benutzerdefinierte Domains konfiguriert werden.

In diesem Beispiel konfigurieren Sie die Domain api.my-project.io. Ersetzen Sie my-project.io durch eine Domain, die Sie besitzen, und api durch Ihren gewünschten Subdomain.

Aktualisieren Sie zunächst Ihre DNS-Einstellungen, damit api.my-project.io auf Ihre <XXXXXX>.stackhero-network.com-Domain zeigt.

  1. Melden Sie sich bei Ihrem Domainanbieter an und greifen Sie auf Ihre DNS-Konfiguration zu.
  2. Erstellen Sie einen neuen Eintrag namens api (oder eine andere Subdomain Ihrer Wahl), setzen Sie den Typ auf CNAME und setzen Sie das Ziel auf <XXXXXX>.stackhero-network.com.

Beispiel für DNS-Konfiguration auf der Cloudflare-DNS-OberflächeBeispiel für DNS-Konfiguration auf der Cloudflare-DNS-Oberfläche

Sobald das DNS konfiguriert ist, können Sie es durch Ausführen des folgenden Befehls validieren:

host api.my-project.io

Sie sollten eine Antwort ähnlich der folgenden sehen:

api.my-project.io is an alias for <XXXXXX>.stackhero-network.com

Die DNS-Propagation kann je nach Anbieter bis zu 24 Stunden dauern. Wenn der host-Befehl nicht die erwartete Antwort liefert, warten Sie bitte und versuchen Sie es später erneut.

Aktualisieren Sie als Nächstes Ihre docker-compose.yml-Datei mit der folgenden Konfiguration:

services:
  api:
    image: traefik/whoami
    hostname: api
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.api.rule=Host(`api.my-project.io`)" # Fügen Sie hier Ihre Domain hinzu
      - "traefik.http.services.api.loadbalancer.server.port=<PORT>" # Ersetzen Sie "<PORT>" durch den Port, auf dem Ihre API hört
      - "traefik.http.routers.api.tls.certresolver=letsencrypt"

Vergessen Sie nicht, api.my-project.io durch Ihre tatsächliche Domain im Traefik-Label Host zu ersetzen.

Stellen Sie Ihren Container mit folgendem Befehl bereit:

docker-compose up -d

Besuchen Sie dann https://api.my-project.io. Sie sollten eine Textseite sehen, die den Hostnamen Ihres Containers api anzeigt.

Nachweis, dass Traefik unseren HTTP-Verkehr mit TLS-Verschlüsselung für unsere neue Domain verwaltetNachweis, dass Traefik unseren HTTP-Verkehr mit TLS-Verschlüsselung für unsere neue Domain verwaltet

Bei der ersten Containereinrichtung kann es einige Sekunden dauern, bis TLS-Zertifikate generiert werden. Wenn Sie einen TLS-Fehler erhalten, warten Sie einige Sekunden und aktualisieren Sie die Seite, um Zeit für die Zertifikatsgenerierung zu geben.

Herzlichen Glückwunsch, Sie haben nun Ihre erste benutzerdefinierte Domain konfiguriert!

Beim Definieren einer Website-URL wie my-company.com ist es eine gute Idee, auch eine "www"-Subdomain einzurichten. Dies stellt sicher, dass Benutzer, die sich über www.my-company.com verbinden, zu Ihrer Hauptseite umgeleitet werden und hilft, Probleme mit doppeltem Inhalt zu vermeiden.

Im folgenden Beispiel werden sowohl my-company.com als auch www.my-company.com behandelt. Benutzer, die auf www.my-company.com zugreifen, werden zu my-company.com umgeleitet:

services:
  frontend:
    image: traefik/whoami
    hostname: frontend
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.frontend.rule=Host(`my-company.com`) || Host(`www.my-company.com`)" # Fügen Sie beide Domains hier hinzu
      - "traefik.http.services.frontend.loadbalancer.server.port=<PORT>" # Ersetzen Sie "<PORT>" durch den Port, auf dem Ihr Frontend hört
      - "traefik.http.routers.frontend.tls.certresolver=letsencrypt"

      # Leiten Sie 'www.my-company.com' zu 'my-company.com' um:
      - 'traefik.http.routers.frontend.middlewares=redirect-www'
      - "traefik.http.middlewares.redirect-www.redirectregex.regex=^https://www.my-company.com/(.*)"
      - "traefik.http.middlewares.redirect-www.redirectregex.replacement=https://my-company.com/$${1}"
      - "traefik.http.middlewares.redirect-www.redirectregex.permanent=true"

Angenommen, Sie haben einen Container, der Ihrer Dokumentationsseite gewidmet ist. Sie möchten möglicherweise https://my-company.com/docs zu diesem Container routen, während andere Anfragen, wie https://my-company.com/, zu Ihrem Frontend-Container gesendet werden. Das folgende Beispiel zeigt, wie dies erreicht wird:

services:
  documentations:
    image: traefik/whoami
    hostname: documentations
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.documentations.rule=Host(`my-company.com`) && PathPrefix(`/docs`)" # Definieren Sie hier das Pfadpräfix
      - "traefik.http.services.documentations.loadbalancer.server.port=<PORT>" # Ersetzen Sie "<PORT>" durch den Port, auf dem Ihr Dokumentationscontainer hört
      - "traefik.http.routers.documentations.tls.certresolver=letsencrypt"

  frontend:
    image: traefik/whoami
    hostname: frontend
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.frontend.rule=Host(`my-company.com`) || Host(`www.my-company.com`)"
      - "traefik.http.services.frontend.loadbalancer.server.port=<PORT>" # Ersetzen Sie "<PORT>" durch den Port, auf dem Ihr Frontend hört
      - "traefik.http.routers.frontend.tls.certresolver=letsencrypt"

      # Leiten Sie 'www.my-company.com' zu 'my-company.com' um:
      - 'traefik.http.routers.frontend.middlewares=redirect-www'
      - "traefik.http.middlewares.redirect-www.redirectregex.regex=^https://www.my-company.com/(.*)"
      - "traefik.http.middlewares.redirect-www.redirectregex.replacement=https://my-company.com/$${1}"
      - "traefik.http.middlewares.redirect-www.redirectregex.permanent=true"

Jetzt wird beim Besuch von https://my-company.com/docs (oder einem beliebigen Unterpfad wie https://my-company.com/docs/something) der Inhalt aus dem documentations-Container angezeigt. Andere Pfade, zum Beispiel https://my-company.com/help, werden vom frontend-Container bedient.

Standardmäßig verbindet sich Traefik mit dem ersten freigegebenen Port des Containers. In einigen Fällen müssen Sie möglicherweise einen bestimmten Port angeben. Das folgende Beispiel zeigt, wie ein benutzerdefinierter Port definiert wird:

services:
  frontend:
    image: traefik/whoami
    hostname: frontend
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.frontend.rule=Host(`my-company.com`)"
      - "traefik.http.routers.frontend.tls.certresolver=letsencrypt"

      # Leiten Sie den Verkehr von 'https://my-company.com' zum 'frontend'-Container auf Port 80
      - "traefik.http.services.frontend.loadbalancer.server.port=80"

Beim Definieren eines Containers in Ihrer docker-compose.yml-Datei sind einige Felder wichtig für bessere Konsistenz und einfachere Verwaltung. Erwägen Sie die Verwendung der folgenden empfohlenen Konfiguration:

services:
  <CONTAINER_NAME>:
    image: traefik/whoami
    hostname: <CONTAINER_NAME>
    container_name: <CONTAINER_NAME>
    restart: unless-stopped
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.<CONTAINER_NAME>.rule=Host(`my-company.com`)"
      - "traefik.http.routers.<CONTAINER_NAME>.tls.certresolver=letsencrypt"

Ersetzen Sie einfach <CONTAINER_NAME> durch den gewünschten Namen für Ihren Container, zum Beispiel frontend.

Beim Erstellen einer Subdomain folgt Let's Encrypt den RFC 952 und 1123, die nur Zeichen im Satz [a-zA-Z0-9-] zulassen.

Obwohl Unterstriche ('_') in DNS-Eintragnamen erlaubt sind, sind sie in Hostnamen nicht akzeptabel. Daher lehnt Let's Encrypt Subdomains wie "my_subdomain.example.com" ab und zeigt den Fehler "Domain name contains an invalid character" an.

Um dieses Problem zu lösen, entfernen Sie einfach alle Unterstriche aus Ihren Subdomains.