[Docker] Kommunikation zwischen Containern über Host-Port ohne Netzwerkfreigabe (host.docker.internal)
Tags: Docker, DevOps, Network, host.docker.internal
1. Problematik
In der Entwicklungsumgebung verwalten wir häufig mehrere Dienste über Docker.
-
App-A(z. B. DRF) befindet sich imnetwork-A. -
App-B(z. B. Nextcloud) befindet sich imnetwork-B. -
Beide Container laufen auf demselben Host-System.
-
App-Bist mit dem8080Port des Hosts verbunden. (z. B.docker run -p 8080:80 ...)
App-A muss App-B über die API aufrufen. Ich möchte nicht umständlich die beiden Netzwerke mit einem Bridge verbinden. Können wir nicht einfach den Host-Port 8080 aufrufen?
Wenn ich in einem Container localhost:8080 oder 127.0.0.1:8080 anrufe, verweist das auf den Container selbst, nicht auf das Host-System.
2. Lösung: host.docker.internal
Die einfachste Lösung ist die Verwendung des speziellen DNS-Namens host.docker.internal.
host.docker.internal: Ein spezieller Hostname, der innerhalb des Containers als IP-Adresse des Host-Systems interpretiert wird.
Wenn ich aus dem Code von App-A (DRF) Nextcloud aufrufe, setze ich die URL wie folgt:
# interner Code von DRF (App-A)
import requests
# Verwenden Sie 'host.docker.internal' anstelle von 'localhost'.
NEXTCLOUD_URL = "http://host.docker.internal:8080"
try:
response = requests.get(NEXTCLOUD_URL)
print(f"Nextcloud Verbindung erfolgreich: {response.status_code}")
except requests.exceptions.ConnectionError:
print("Nextcloud Verbindung fehlgeschlagen")
Das gleiche gilt, wenn ich innerhalb des Containers mit curl teste.
# Ausgeführt innerhalb des App-A-Containers
curl http://host.docker.internal:8080
3. ⚠️ Wichtig: Einstellungen für Linux-Hosts
Benutzer von Docker Desktop (macOS, Windows) haben host.docker.internal standardmäßig aktiviert.
In einer Linux-Host-Umgebung muss diese Einstellung jedoch manuell hinzugefügt werden. Das spezielle Schlüsselwort host-gateway kann verwendet werden, um die Host-IP zuzuordnen.
Methode 1: Bei der Verwendung von docker run
Fügen Sie das Flag --add-host hinzu.
docker run \
--add-host=host.docker.internal:host-gateway \
--network network-A \
my-drf-app-image
Methode 2: Bei der Verwendung von docker-compose.yml
Fügen Sie extra_hosts zum App-A (DRF)-Dienst hinzu.
services:
drf-app:
image: my-drf-app-image
networks:
- network-A
extra_hosts:
# Zuordnung von host.docker.internal zur Host-IP (host-gateway)
- "host.docker.internal:host-gateway"
# ... (Definition von network-A) ...
4. Zusammenfassung
Bei der Kommunikation zwischen getrennten Docker-Netzwerken müssen Sie kein komplexes Netzwerk erstellen.
-
Verbinden Sie den Ziel-Container (Nextcloud) mit dem Host-Port (
8080). -
Der aufrufende Container (DRF) sendet die Anfrage an
http://host.docker.internal:8080. -
Wenn der Host ein Linux ist, denken Sie daran, im aufrufenden Container
extra_hosts(host.docker.internal:host-gateway) einzufügen.
Es sind keine Kommentare vorhanden.