🐳 Docker: Als netwerken samenvoegen te veel gedoe is en je 'snel' via hostpoorten wilt communiceren

De standaardmanier om containers met elkaar te laten communiceren, is door een gemeenschappelijk bridge-netwerk op te zetten en ze aan te roepen via hun servicenaam (bijv. http://app-b:8080). Soms zijn er echter omstandigheden waarin dit niet haalbaar is.

Gebruik deze methode in deze 'lastige situaties'

  • Wanneer je wilt communiceren met services die direct op de host zijn geïnstalleerd: Als een database of Redis direct op het host-besturingssysteem is geïnstalleerd en niet in een container, waardoor netwerken samenvoegen onmogelijk is.
  • Wanneer je bang bent de netwerkinstellingen van een externe container aan te passen: Als je je eigen container niet zomaar wilt toevoegen aan complexe netwerkinstellingen van een container die je niet beheert, uit angst voor storingen.
  • Wanneer je 'tijdelijk' een verbinding wilt controleren tijdens lokale ontwikkeling: Als je snel wilt testen of een verzoek aankomt bij een service die via een hostpoort is geopend, zonder je zorgen te maken over netwerkontwerp.

In zulke gevallen is host.docker.internal een handige truc.

Containercommunicatie via host


De oplossing: "Een venster naar de buitenwereld" via host.docker.internal

Binnen een container verwijst 127.0.0.1 alleen naar de container zelf. Met het speciale domein host.docker.internal omzeil je de containerisolatie en krijg je toegang tot het IP-adres van de hostmachine.

Python (DRF) codevoorbeeld:

# Gebruik 'host.docker.internal' in plaats van 'localhost' om via de hostpoort te communiceren.
# Als App-B is gebonden aan poort 8080 van de host, roep je het als volgt aan.
NEXTCLOUD_URL = "http://host.docker.internal:8080"

response = requests.get(NEXTCLOUD_URL)


⚠️ Voor Linux-gebruikers is 'handmatige configuratie' essentieel

Hoewel Docker Desktop (Mac/Windows) dit standaard ondersteunt, zal Docker op een pure Linux-server dit domein niet automatisch herkennen. Je moet tijdens het bouwen of uitvoeren expliciet aangeven dat 'dit domein verwijst naar het host-IP'.

Docker Compose configuratievoorbeeld:

services:
  drf-app:
    image: my-drf-app-image
    extra_hosts:
      # Verklaring dat host.docker.internal toegang geeft tot de host-gateway
      - "host.docker.internal:host-gateway"


Dit is niet altijd de beste oplossing

Nogmaals, deze methode is eerder een laatste redmiddel.

  1. De beste methode: Een gemeenschappelijk bridge-netwerk aanmaken en communiceren via containernamen (het veiligst).
  2. Waarom deze methode gebruiken: Wanneer je toegang nodig hebt tot processen die direct op de host draaien, of in een 'geïsoleerde' omgeving waar netwerkstructuren niet kunnen worden samengevoegd.

Deze 'noodoplossing', die ik vorig jaar al beschreef, dient alleen als een laatste redmiddel wanneer de standaardaanpak niet mogelijk is!