[Docker] Communiceren tussen containers zonder netwerksamenwerking, via de hostpoort (host.docker.internal)



Tags: Docker, DevOps, Networking, host.docker.internal

1. Probleemstelling

Het komt vaak voor dat meerdere diensten in een ontwikkelomgeving met Docker worden beheerd.

  • App-A (bijv. DRF) bevindt zich in network-A.

  • App-B (bijv. Nextcloud) bevindt zich in network-B.

  • Beide containers draaien op dezelfde hostmachine.

  • App-B is gebonden aan de 8080 poort van de host. (bijv. docker run -p 8080:80 ...)

App-A moet App-B aanroepen via de API. Ik wil die twee netwerken niet lastig verbinden. Is het niet mogelijk om gewoon de hostpoort 8080 aan te roepen?

Als ik binnen de container localhost:8080 of 127.0.0.1:8080 aanroep, verwijst dit naar de container zelf en niet naar de hostmachine.

2. Oplossing: host.docker.internal

De eenvoudigste oplossing is om de speciale DNS-naam host.docker.internal te gebruiken.

host.docker.internal: een speciale hostnaam die binnen de container wordt geïnterpreteerd als het IP-adres van de hostmachine.

Wanneer je vanuit de code van App-A (DRF) Nextcloud aanroept, stel je de URL in als volgt:

# Interne code in DRF (App-A)
import requests

# Gebruik 'host.docker.internal' in plaats van 'localhost'.
NEXTCLOUD_URL = "http://host.docker.internal:8080"

try:
    response = requests.get(NEXTCLOUD_URL)
    print(f"Nextcloud verbinding succesvol: {response.status_code}")
except requests.exceptions.ConnectionError:
    print("Nextcloud verbinding mislukt")

Hetzelfde geldt wanneer je binnen de container test met curl.

# Uitvoeren vanuit de App-A container
curl http://host.docker.internal:8080

3. ⚠️ Belangrijk: Configuratie van de Linux host

Voor gebruikers van Docker Desktop (macOS, Windows) werkt host.docker.internal standaard.

Echter, in een Linux host omgeving moet je deze instelling handmatig toevoegen. Je kunt het speciaal trefwoord host-gateway gebruiken om het host IP te mappen.

Methode 1: Bij gebruik van docker run

Voeg de --add-host vlag toe.

docker run \
  --add-host=host.docker.internal:host-gateway \
  --network network-A \
  my-drf-app-image

Methode 2: Bij gebruik van docker-compose.yml

Voeg extra_hosts toe aan de App-A (DRF) service.

services:
  drf-app:
    image: my-drf-app-image
    networks:
      - network-A
    extra_hosts:
      # Mapt host.docker.internal naar het IP van de hostmachine (host-gateway)
      - "host.docker.internal:host-gateway"

# ... (definitie van network-A) ...

4. Samenvatting

Bij communicatie tussen gescheiden docker-netwerken is het niet nodig om de netwerken complex met elkaar te verbinden.

  1. Bind de container die je aanroept (Nextcloud) aan de hostpoort (8080).

  2. Doe een verzoek vanaf de aanroepende container (DRF) naar http://host.docker.internal:8080.

  3. Als de host Linux is, vergeet dan niet om de extra_hosts (host.docker.internal:host-gateway) instelling aan de aanroepende container toe te voegen.