HOWTO · Docker
So konfigurieren Sie host.docker.internal unter Linux
Konfigurieren Sie host.docker.internal unter Linux mit der host-gateway-Zuordnung von Docker. Überprüfen Sie anschließend den Zugriff eines Containers auf einen Host-Dienst und beheben Sie Verbindungsprobleme.
Auf dieser Seite
Um von einem Linux-Container aus einen Dienst auf seinem Docker-Host zu erreichen, erstellen Sie den Container mit --add-host=host.docker.internal:host-gateway auf einer Docker-Engine-Installation, die den Wert host-gateway unterstützt. Richten Sie die Anfrage anschließend an host.docker.internal und den Port, auf dem der Dienst Verbindungen entgegennimmt. Dabei geht der Datenverkehr vom Container zum Host. Einen Container vom Host aus zu erreichen, ist eine andere Aufgabe und wird üblicherweise über einen veröffentlichten Port wie -p 8080:80 gelöst.
Was host.docker.internal unter Linux bedeutet
host.docker.internal ist ein Hostname, über den ein Container seinen Host ansprechen kann. Es ist kein Shell-Befehl. Bei Docker Engine unter Linux muss der Name möglicherweise beim Erstellen des Containers zugeordnet werden. Mit dem speziellen Wert host-gateway kann Docker die Gateway-Adresse für die jeweilige Engine-Konfiguration bereitstellen. So müssen Sie keine Bridge-IP-Adresse erraten. Ob dieser Wert unterstützt wird, hängt von der Docker-Engine-Konfiguration ab. Wenn Docker ihn zurückweist, prüfen Sie die Dokumentation Ihrer installierten Engine oder verwenden Sie die für Ihr Netzwerk konfigurierte Host-Adresse.
Die Zuordnung gilt nur für den Container, für den sie festgelegt wurde. Sie startet keinen Dienst auf dem Host, veröffentlicht keinen Container-Port und macht keinen Dienst verfügbar, der nur innerhalb eines anderen Containers lauscht.
host.docker.internal einem Linux-Container hinzufügen
Fügen Sie die Zuordnung beim Erstellen des Containers zum Befehl docker run hinzu:
docker run --rm -it --add-host=host.docker.internal:host-gateway IMAGE COMMAND
Ersetzen Sie IMAGE und COMMAND durch das benötigte Image und den gewünschten Prozess. Bei einer dauerhaft laufenden Anwendung ergänzen Sie dieselbe Option --add-host in der Dienstkonfiguration und erstellen den Container neu. Eine Zuordnung lässt sich nicht zu einem bereits laufenden Container hinzufügen. Die Option funktioniert auch mit einem benutzerdefinierten Netzwerk. Für diesen Hostnamen ist ein solches Netzwerk jedoch nicht erforderlich.
Hostverbindung vom Container aus überprüfen
Starten Sie auf dem Host einen Dienst, der Verbindungen über eine vom Container erreichbare Adresse annimmt. Für einen vorübergehenden HTTP-Test können Sie auf dem Host python3 -m http.server 8000 --bind 0.0.0.0 ausführen. Durch die Bindung an 0.0.0.0 lauscht dieser Testserver auf den Netzwerkschnittstellen des Hosts. Verwenden Sie diese Einstellung nur, wenn Host-Firewall und Netzwerkerreichbarkeit dafür geeignet sind. Lassen Sie den Server während des Tests laufen.
Erstellen Sie einen Testcontainer mit der Zuordnung und fragen Sie denselben Port ab. Wenn Docker das Image curlimages/curl herunterladen kann, führen Sie beispielsweise docker run --rm --add-host=host.docker.internal:host-gateway curlimages/curl:latest http://host.docker.internal:8000/ aus. Dieses Image enthält curl. Bei einem anderen Image muss ein geeigneter HTTP-Client installiert sein. Eine Antwort des Servers, etwa eine HTTP-Verzeichnisauflistung, bestätigt, dass Namensauflösung, Routing und Dienst-Port zusammen funktionieren. Dieser Test mit Docker und einem Host-Dienst hängt von Ihrer lokalen Docker-Engine und Netzwerkkonfiguration ab. Er wird daher nicht von der isolierten Code-Umgebung dieses Artikels ausgeführt.
Verbindungsprobleme beheben
- Wird der Name nicht aufgelöst, prüfen Sie, ob der Container mit der Zuordnung
--add-host=host.docker.internal:host-gatewayerstellt wurde und Ihre Docker Enginehost-gatewayunterstützt. Erstellen Sie den Container neu, nachdem Sie seine Konfiguration geändert haben. - Wird der Name aufgelöst, aber die Anfrage läuft in einen Timeout oder wird abgewiesen, prüfen Sie, ob der Host-Dienst läuft und am erwarteten Port lauscht. Ein Dienst, der nur an
127.0.0.1gebunden ist, kann Anfragen vom Host selbst annehmen, während er Verbindungen über das Containernetzwerk zurückweist. Konfigurieren Sie eine erreichbare Bind-Adresse und beschränken Sie den Zugriff mit der Host-Firewall. - Prüfen Sie, ob die URL den tatsächlichen Port des Dienstes verwendet. Der Port in der Anfrage des Containers ist der Port des Host-Dienstes. Docker verwendet die Option
-pzum Veröffentlichen eines Container-Ports; für diese Richtung des Datenverkehrs ist sie nicht erforderlich. - Ist die Zuordnung vorhanden und der Dienst vom Host, aber nicht vom Container aus erreichbar, prüfen Sie die Host-Firewallregeln und die Netzwerkkonfiguration der Docker Engine. Gehen Sie nicht davon aus, dass
172.17.0.1überall gilt oder mitlocalhostgleichzusetzen ist. Bridge-Adressen unterscheiden sich je nach Konfiguration.
Häufige Fragen
Was bewirkt host.docker.internal? Der Hostname ermöglicht einem Container die Verbindung zu einem Dienst auf seinem Host, sofern er diesem Container zugeordnet wurde.
Unterscheidet sich die Einrichtung unter Linux von Docker Desktop? Ja. Dieser Artikel behandelt Docker Engine unter Linux, wo Sie die Zuordnung mit host-gateway beim Erstellen des Containers hinzufügen können. Docker Desktop bietet ein eigenes Netzwerkverhalten für den Zugriff auf den Host. Beachten Sie die Dokumentation für die von Ihnen verwendete Plattform und Engine.
Brauche ich ein benutzerdefiniertes Docker-Netzwerk? Nein. Auf einer unterstützten Engine genügt die Zuordnung mit --add-host für diesen Hostnamen. Ein benutzerdefiniertes Netzwerk kann für andere Anforderungen an Isolation oder Diensterkennung nützlich sein.
Wie kann ich die Verbindung testen? Starten Sie einen Host-Dienst an einer erreichbaren Schnittstelle und einem erreichbaren Port. Fragen Sie dann von einem mit der Zuordnung erstellten Container http://host.docker.internal:PORT/ ab. Stellen Sie sicher, dass das Container-Image einen HTTP-Client wie curl enthält und die Host-Firewall den Datenverkehr zulässt.