[{"content":"Container networking tends to work fine right up until it doesn\u0026rsquo;t, and when it breaks the failure mode is rarely obvious. A service can\u0026rsquo;t reach another service, a port that\u0026rsquo;s supposedly published refuses connections, or DNS resolves inside one container but not another. This post walks through a systematic approach to diagnosing these problems, using the tools Docker gives you out of the box.\nStart with the network topology Before touching logs or packet captures, get a clear picture of what networks exist and which containers are attached to them. Docker Compose creates a default bridge network per project, but multi-network setups are common once you start isolating a database tier from a public-facing tier.\ndocker network ls docker network inspect my-app_default The inspect output lists every container attached to the network along with its internal IP address. If a container you expect to see isn\u0026rsquo;t listed, that\u0026rsquo;s usually the actual bug — not a firewall rule or a misconfigured DNS entry.\nA quick mental model helps here:\nNetwork driver Typical use case Containers reach each other by bridge (default) Single-host multi-container apps Container name (via embedded DNS) host Performance-sensitive services, no isolation localhost overlay Multi-host Swarm/Kubernetes-style clusters Service name via overlay DNS none Fully isolated containers Not at all Most \u0026ldquo;container A can\u0026rsquo;t talk to container B\u0026rdquo; issues on a single host come down to the two containers not being on the same bridge network at all.\nCheck DNS resolution from inside the container Docker\u0026rsquo;s embedded DNS server resolves container and service names automatically, but only for containers on a shared user-defined network. The default bridge network (literally named bridge) does not support name-based resolution — only IP addresses work there. This trips people up constantly when they expect ping web to work outside of Compose.\nExec into the container and test resolution directly:\ndocker exec -it my-app_api_1 sh -c \u0026#34;getent hosts db || nslookup db\u0026#34; If that fails but docker network inspect shows both containers on the same network, check whether the network is user-defined:\ndocker inspect my-app_api_1 --format \u0026#39;{{json .NetworkSettings.Networks}}\u0026#39; | jq If the container is only attached to the default bridge, add both services to a user-defined network in your Compose file:\nservices: api: image: my-app/api networks: - backend db: image: postgres:16 networks: - backend networks: backend: driver: bridge Verify port publishing, not just container listening A common source of confusion: a service listening inside the container doesn\u0026rsquo;t automatically mean it\u0026rsquo;s reachable from the host. EXPOSE in a Dockerfile is documentation, not enforcement — it doesn\u0026rsquo;t publish anything. Only -p (or ports: in Compose) actually maps a container port to the host.\ndocker ps --format \u0026#39;table {{.Names}}\\t{{.Ports}}\u0026#39; If the PORTS column is empty or missing the port you expect, the fix is in your run command or Compose file:\ndocker run -d -p 8080:80 --name web nginx Also check what the process inside the container is actually bound to. A service bound to 127.0.0.1 inside the container is unreachable from outside it, even with correct port publishing, because the container\u0026rsquo;s loopback interface is separate from the host\u0026rsquo;s. The fix is almost always to bind to 0.0.0.0 in the application config.\ndocker exec -it web sh -c \u0026#34;netstat -tlnp || ss -tlnp\u0026#34; Trace the actual path with a throwaway debug container When name resolution and port publishing both look correct but traffic still doesn\u0026rsquo;t get through, attach a minimal debugging container to the same network rather than adding tools to your production image:\ndocker run --rm -it --network my-app_backend nicolaka/netshoot bash netshoot bundles curl, dig, tcpdump, iproute2, and friends, and staying out of your production images with these tools keeps them smaller. From inside it:\ndig db curl -v http://api:3000/health tcpdump -i eth0 host db This isolates the problem to either the network layer (packets aren\u0026rsquo;t arriving) or the application layer (packets arrive, but the service rejects or mishandles them).\nInspect iptables when things get stranger Docker manages its own iptables rules for NAT and port forwarding, and on Linux hosts these can conflict with rules from other tools (firewalls, VPN clients, Kubernetes\u0026rsquo; kube-proxy on the same host). If a port is published, DNS resolves, and the target process is bound correctly — but connections still time out — check the NAT table:\nsudo iptables -t nat -L DOCKER -n -v Look for a DNAT rule matching your published port. If it\u0026rsquo;s missing, Docker\u0026rsquo;s networking state may be out of sync with the running containers, which usually means a restart of the Docker daemon:\nsudo systemctl restart docker This is a blunt instrument, so treat it as a last resort after the network- and application-layer checks above have been ruled out — it briefly interrupts every running container on the host.\nA minimal checklist When a container networking issue comes up, work through these in order rather than guessing:\nConfirm both containers are attached to the same user-defined network (docker network inspect). Confirm DNS resolves the target name from inside the source container (getent hosts, dig). Confirm the target process is bound to 0.0.0.0, not 127.0.0.1, inside its container. Confirm the port is actually published if you\u0026rsquo;re connecting from the host (docker ps). Use a throwaway netshoot container to isolate network-layer from application-layer failures. Only after that, look at iptables and the Docker daemon itself. Most container networking bugs are one of the first four items. The remaining two are worth knowing about, but reaching for them first usually means skipping past the actual cause.\n","permalink":"https://blog.timhoncoop.nl/posts/debugging-docker-networking/","summary":"A practical walkthrough of diagnosing container connectivity issues: DNS resolution, bridge networks, port publishing, and the tools that actually help.","title":"Debugging Docker Networking"}]