Docs / Troubleshooting / Troubleshoot Docker Container Networking Issues

Troubleshoot Docker Container Networking Issues

By Admin · Mar 15, 2026 · Updated Apr 23, 2026 · 217 views · 4 min read

Docker networking issues are among the most common problems when running containerized applications. Containers that can't reach each other, can't access the internet, or aren't reachable from outside the host all have specific, diagnosable causes. This guide covers systematic troubleshooting of Docker networking problems.

Common Networking Issues

  • Container can't reach the internet
  • Containers can't communicate with each other
  • Published ports aren't accessible from outside
  • DNS resolution fails inside containers

Diagnostic Commands

# Check container network settings
docker inspect --format='{{json .NetworkSettings}}' container_name | jq

# List Docker networks
docker network ls
docker network inspect bridge

# Check container IP
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container_name

# Test connectivity from inside a container
docker exec -it container_name sh -c "ping -c 3 8.8.8.8"
docker exec -it container_name sh -c "nslookup google.com"
docker exec -it container_name sh -c "curl -v http://other-container:8080"

# Check Docker DNS
docker exec -it container_name cat /etc/resolv.conf

# Check iptables rules Docker creates
sudo iptables -L -n -t nat | grep -A5 DOCKER
sudo iptables -L DOCKER -n

Fix: Container Can't Reach Internet

# Check IP forwarding (must be enabled)
cat /proc/sys/net/ipv4/ip_forward
# If 0, enable it:
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward
echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.d/99-docker.conf

# Check if Docker's NAT rules exist
sudo iptables -t nat -L POSTROUTING -n | grep 172.17
# Should see: MASQUERADE all -- 172.17.0.0/16 0.0.0.0/0

# Restart Docker to recreate iptables rules
sudo systemctl restart docker

# Check if firewall is interfering
sudo ufw status
# If UFW is enabled, Docker may conflict with it
# Fix: Allow Docker subnet
sudo ufw allow from 172.16.0.0/12

# Check DNS inside container
docker run --rm alpine nslookup google.com
# If DNS fails, set DNS explicitly:
docker run --dns 1.1.1.1 --rm alpine nslookup google.com

# Or configure Docker daemon DNS
echo '{"dns": ["1.1.1.1", "8.8.8.8"]}' | sudo tee /etc/docker/daemon.json
sudo systemctl restart docker

Fix: Containers Can't Talk to Each Other

# Default bridge network does NOT support DNS resolution between containers
# Containers on default bridge can only communicate by IP, not name

# Fix: Create a user-defined network
docker network create app-network

# Run containers on the same network
docker run -d --name web --network app-network nginx
docker run -d --name api --network app-network my-api

# Now they can reach each other by name:
docker exec web curl http://api:8080

# For Docker Compose: services automatically get a shared network
# docker-compose.yml creates a network named "projectname_default"

# Check which network a container is on
docker inspect container_name | jq '.[0].NetworkSettings.Networks'

# Connect existing container to a network
docker network connect app-network existing-container

Fix: Published Ports Not Accessible

# Check port mapping
docker port container_name
docker ps --format "{{.Names}}: {{.Ports}}"

# Verify the app inside listens on 0.0.0.0, not 127.0.0.1
docker exec container_name ss -tlnp

# Check if another process is using the port
sudo ss -tlnp | grep :80

# Check Docker proxy process
ps aux | grep docker-proxy

# Test from the host
curl localhost:80

# Check host firewall
sudo iptables -L INPUT -n | grep 80
sudo ufw allow 80/tcp

# If behind Cloudflare/cloud firewall, check there too

Fix: Docker Compose Networking Issues

# In docker-compose.yml, services communicate by service name
# Wrong: http://localhost:3000 (this is the container's localhost)
# Right: http://service-name:3000

# Common mistake: using "localhost" in DATABASE_URL
# Wrong: DATABASE_URL=postgresql://localhost:5432/mydb
# Right: DATABASE_URL=postgresql://db:5432/mydb (where "db" is the service name)

# Check compose network
docker network ls | grep projectname
docker network inspect projectname_default

# Recreate networks
docker compose down
docker compose up -d

Advanced Debugging

# Use nicolaka/netshoot for debugging (full networking toolkit)
docker run -it --network container:problematic-container nicolaka/netshoot

# Inside netshoot, you share the network namespace:
ip addr
ss -tlnp
tcpdump -i any port 80
nslookup service-name 127.0.0.11  # Docker DNS

# Check for MTU issues (common in cloud/VPS environments)
docker exec container_name ping -c 3 -M do -s 1472 8.8.8.8
# If this fails, try smaller sizes — MTU issue
# Fix: set MTU on Docker network
docker network create --opt com.docker.network.driver.mtu=1450 app-network

Best Practices

  • Always use user-defined networks instead of the default bridge for service-to-service communication
  • Use service names, not IPs for container-to-container communication
  • Check IP forwarding if containers can't reach the internet
  • Configure Docker DNS in daemon.json if containers have DNS issues
  • Use nicolaka/netshoot for comprehensive network debugging inside containers
  • Check for MTU mismatches if connections timeout or have partial data transfer

Was this article helpful?