Docker Networking Explained: Bridge, Host, Overlay, and Custom Networks
The Default Bridge Network
When you run a container without specifying a network, it joins the default bridge network. This network has one significant limitation: containers cannot reach each other by name. You must use IP addresses, which change on restart.
docker run -d --name web nginx
docker run -d --name app myapp
docker exec app curl http://web # FAILS on default bridge
docker exec app curl http://172.17.0.2 # works but brittle
---
Custom Networks: The Right Way
Create a custom bridge network and containers on it can reach each other by name:
docker network create app_net
docker run -d --name db --network app_net postgres:16
docker run -d --name api --network app_net myapp
docker exec api curl http://db:5432 # works — Docker DNS resolves 'db'
Docker runs a built-in DNS server for custom networks. Container names become hostnames.
---
Inspecting Networks
docker network ls # list networks
docker network inspect app_net # detailed config + connected containers
docker inspect api | grep -A20 Networks # which networks a container is on
---
Connecting a Container to Multiple Networks
docker network connect infra_net api # add api to a second network
docker network disconnect app_net api # remove from a network
In Compose:
services:
api:
networks:
- app_net
- infra_net
---
Port Publishing
# Publish to all interfaces
docker run -p 8080:80 nginx # host:8080 → container:80
# Publish to localhost only (safer for non-public services)
docker run -p 127.0.0.1:5432:5432 postgres
# Publish to a random host port
docker run -p 80 nginx
docker port <container> # find the assigned port
---
Host Networking
docker run --network host nginx
The container shares the host's network stack — no NAT, no port publishing needed. Useful for performance-sensitive workloads or tools that need to bind to multiple ports. Not available on Docker Desktop (Mac/Windows) — host networking only works on Linux Docker.
---
Network Isolation for Security
Create separate networks for different trust levels:
services:
frontend:
networks: [public_net, internal_net]
api:
networks: [internal_net, db_net]
postgres:
networks: [db_net] # only reachable by api
networks:
public_net: {} # frontend faces the internet (via nginx)
internal_net: {} # frontend ↔ api
db_net: {} # api ↔ database only
---
Debugging Network Issues
# Check if containers can reach each other
docker exec api ping db
docker exec api curl -v http://db:5432
# Check DNS resolution inside a container
docker exec api nslookup db
# Inspect iptables rules Docker adds
iptables -L DOCKER -n
Practice networking in the ShellGenius Docker Labs — the network-microservices, port-conflict, and network-isolate challenges use real multi-container network scenarios.