Essential Docker Networking Troubleshooting Commands

Here is a collection of essential Docker network troubleshooting commands and techniques, ranging from quick inspect tricks to advanced network namespace debugging.

Level 1: Quick Layout Auditing

Before diving into a container, use the host CLI to map out your subnets and see who is talking to what.

1. Map Every Container to Its IP Address

Instead of looking through pages of JSON from docker network inspect, use a Go template format string to instantly spit out a list of all custom networks, the containers attached to them, and their internal IP addresses:

Bash

docker network ls -q | xargs docker network inspect --format \
'{{range .}}{{ .Name }}:{{range .Containers}} {{.Name}} -> {{.IPv4Address}}{{end}}{{end}}'
2. Trace a Container’s Network Configuration

If you have a specific container that can’t connect out, run this to see exactly which virtual Docker bridge networks it belongs to and what gateway it is using to reach the internet:

Bash

docker inspect <container_name> --format \
'{{range $net, $cfg := .NetworkSettings.Networks}}{{$net}} -> IP: {{$cfg.IPAddress}} | GW: {{$cfg.Gateway}}{{"\n"}}{{end}}'

Level 2: Runtime Network Probing (The Sandbox Way)

Containers stripped of standard network tools (like ping, curl, or nslookup) make troubleshooting internal DNS tricky. Instead of modifying your production application container to install tools, spin up a temporary diagnostics container inside your exact application network stack.

1. Test Internal Embedded DNS Resolution

Docker Compose automatically sets up an internal DNS server at 127.0.0.11 for service discovery. If web-app can’t reach your postgres database container by its service name, spin up an alpine diagnostic container on that network to test resolution:

Bash

docker run --rm -it --network=<your_compose_network_name> alpine nslookup postgres
2. Verify Port Connectivity

If DNS resolves correctly but connections still timeout, test if the application port is actually listening and accepting traffic using nc (Netcat):

Bash

docker run --rm -it --network=<your_compose_network_name> alpine nc -zv postgres 5432
  • Success response: postgres (172.18.0.3:5432) open
  • Failure response: Connection refused (The container is up, but the app inside isn’t running or listening on that port).

Level 3: Deep Host-Level Troubleshooting (SRE Mode)

Sometimes Docker commands lie, or the issue is rooted in the host Linux kernel’s routing tables and iptables rules.

1. Access a Container’s Network Namespace Directly From the Host

Every Docker container runs in an isolated Linux network namespace (netns). You don’t actually need to enter a container to run network diagnostics on it; you can force your host’s native tools (like ip addr or ss) to run inside the container’s private sandbox.

First, get the Process ID (PID) of your stuck container:

Bash

PID=$(docker inspect --format '{{.State.Pid}}' <container_name>)

Now, pass that PID to the host’s nsenter command to view the container’s internal interfaces and socket status using host-level utilities:

Bash

# View actual internal interfaces from the host
sudo nsenter -t $PID -n ip addr
# View real-time active connections and listening ports inside the container
sudo nsenter -t $PID -n ss -tulpn

2. Capture Traffic with tcpdump

If you suspect an application protocol error or dropping packets between containers, you can attach tcpdump directly to the container’s network stack from the host interface using nsenter:

Bash

sudo nsenter -t $PID -n tcpdump -i any port 80 -vv

(This allows you to sniff live HTTP traffic running through a container without having to install a packet capture tool inside the container itself).

Common Multi-Server Pitfall: Subnet Overlaps

When managing 20+ servers on an enterprise or on-premise network, a common point of failure occurs when a Docker Compose auto-generated bridge network clashes with your physical company Wi-Fi/LAN subnets.

If Docker auto-assigns a pool like 192.168.1.0/24 to a local compose stack, and your central database server lives on that same subnet in your physical data center, your containers will never be able to reach that physical database—they will think the traffic belongs inside the host.

The Fix: Enforce Strict IPAM in Compose

For production servers, explicitly declare your subnets in your docker-compose.yml to prevent accidental overlaps with corporate infrastructure:

YAML

networks:
app-tier:
driver: bridge
ipam:
config:
- subnet: 172.28.10.0/24
gateway: 172.28.10.1

Leave a Reply