Netzwerkprobleme zwischen Containern debuggen
Netzwerkprobleme zwischen Containern debuggen
Container im selben Stack können sich gegenseitig nicht erreichen — diese Checkliste führt systematisch zur Ursache.
Das häufigste Missverständnis: localhost
Innerhalb eines Containers ist localhost der Container selbst — nicht der Host und nicht ein anderer Container. Wer curl http://localhost:3000 in Container A ausführt, erreicht Port 3000 von Container A, nicht von Container B.
Richtig: Andere Container über ihren Service-Namen ansprechen.
Checkliste Schritt für Schritt
1. Gleiches Netzwerk prüfen
docker inspect containerA --format '{{json .NetworkSettings.Networks}}'
docker inspect containerB --format '{{json .NetworkSettings.Networks}}'
Beide müssen im selben Netzwerk sein. Bei Compose passiert das automatisch — außer ein Container hat network_mode: host oder ein explizit anderes Netzwerk zugewiesen.
2. Service-Namen vs. Container-Namen
In Compose-Stacks ist der Service-Name der DNS-Name, nicht der Container-Name:
services:
api: # ← dieser Name ist der DNS-Name
image: myapi
web:
image: nginx
# Richtig: proxy_pass http://api:3000;
# Falsch: proxy_pass http://myproject-api-1:3000;
3. Konnektivität testen
# Ping-Test (erfordert iputils-ping im Container)
docker exec containerA ping containerB
# HTTP-Test — direkter und praktikabler
docker exec containerA curl http://containerB:3000
# DNS-Auflösung prüfen
docker exec containerA nslookup containerB
4. Lauscht der Zieldienst überhaupt?
docker exec containerB ss -tlnp
# oder
docker exec containerB netstat -tlnp
Wenn der Dienst nur auf 127.0.0.1:3000 lauscht statt auf 0.0.0.0:3000, ist er nur innerhalb des Containers selbst erreichbar — nicht von anderen Containern.
5. Firewall-Regeln auf dem Host
iptables-Regeln auf dem Host können Docker-internen Traffic blockieren:
sudo iptables -L DOCKER-USER -n
Docker verwaltet seine eigenen Regeln — manuelle Eingriffe können unbeabsichtigt den Inter-Container-Traffic sperren.
DNS funktioniert nur auf user-defined Networks
Das ist ein wichtiger Docker-Gotcha:
- Default bridge (
docker0): Kein DNS. Container können sich nur per IP-Adresse erreichen — und IPs ändern sich bei jedem Start. - User-defined bridge (manuell erstellt oder via Compose): Eingebauter DNS-Server. Container erreichbar per Service-/Container-Name.
Compose erstellt automatisch ein user-defined Network. Wer Container manuell mit docker run startet, muss ein Netzwerk explizit erstellen:
docker network create mynet
docker run --network mynet --name api myapi
docker run --network mynet --name web nginx
Jetzt kann web den Host api per Name auflösen.
Netzwerkübersicht
# Alle Netzwerke anzeigen
docker network ls
# Container in einem Netzwerk anzeigen
docker network inspect mynet --format '{{range .Containers}}{{.Name}} {{end}}'
Häufige Ursachen auf einen Blick
| Problem | Diagnose | Lösung |
|---------|----------|--------|
| Container in unterschiedlichen Netzwerken | docker inspect → Networks vergleichen | Beide in dasselbe Netzwerk |
| localhost statt Service-Name | Logs / Konfiguration | Service-Name verwenden |
| Dienst lauscht nur auf 127.0.0.1 | ss -tlnp im Container | App-Konfiguration auf 0.0.0.0 |
| Default bridge (kein DNS) | docker network ls | User-defined Network verwenden |
Weiterführend
Die hier eingesetzten Tools — ss, ip, ping, dig — sind klassische Linux-Netzwerkwerkzeuge. Mehr dazu auf nolr.nexon.cyou.