Docker networking cheatsheet.
Network drivers
- bridge (default): isolated network on host.
- host: container shares host’s network stack (Linux).
- none: no networking.
- overlay: multi-host (Swarm).
- macvlan: container gets its own MAC + IP on host network.
bridge basics
docker network create mynet
docker run -d --name a --network mynet alpine sleep 1000
docker run -d --name b --network mynet alpine sleep 1000
docker exec a ping b # works (DNS by name)
docker exec a getent hosts b
User-defined bridge networks have automatic DNS between containers. The default bridge does NOT.
host network (Linux only)
docker run -d --network host nginx
Container uses host’s network — no port mapping needed. Use sparingly (security, port conflicts).
Multiple networks
docker run -d --name web --network frontend nginx
docker network connect backend web
Container reachable on both networks.
Port publishing
docker run -p 8080:80 nginx # host:container
docker run -p 127.0.0.1:8080:80 nginx # bind specific interface
docker run -p 8080:80/udp app
docker run -p 8080-8090:8080-8090 app # range
docker run -P nginx # random host ports
DNS
Containers on user-defined networks resolve each other by:
- Container name (
--name web). - Network alias (
--network-alias myname). - Service name (compose).
docker run -d --network mynet --name web --network-alias api app
# Both `web` and `api` resolve to this container.
Container IP
docker inspect --format='{{.NetworkSettings.Networks.mynet.IPAddress}}' web
Don’t rely on IPs — they change. Use names.
Internal-only network
docker network create --internal backend
No external connectivity. Good for DBs.
DNS to host
On Docker Desktop (Mac/Windows): host.docker.internal resolves to host.
On Linux: add it manually:
docker run --add-host=host.docker.internal:host-gateway app
/etc/hosts
docker run --add-host=api.local:1.2.3.4 app
–link (legacy, don’t use)
docker run -d --link db:db app
Replaced by user-defined networks. Avoid.
Compose networks
services:
web: { networks: [frontend, backend] }
db: { networks: [backend] }
proxy: { networks: [frontend] }
networks:
frontend:
backend:
internal: true
Inspect
docker network ls
docker network inspect mynet
docker network inspect mynet --format='{{json .Containers}}' | jq
ipam (IP address management)
docker network create \
--subnet 172.20.0.0/16 \
--gateway 172.20.0.1 \
--ip-range 172.20.1.0/24 \
mynet
docker run --network mynet --ip 172.20.1.100 app
Specific IPs (rarely needed).
Limit bandwidth (with tc on host)
Docker doesn’t natively limit BW. Use tc on the container’s interface or run in K8s with CNI that supports it.
Troubleshooting
# Can a → b?
docker exec a ping b
docker exec a nc -zv b 80
docker exec a curl -v http://b/
# Is the port open inside container?
docker exec b netstat -tlnp # or ss -tlnp
# Is it published on host?
docker port web
netstat -tlnp | grep 8080 # host
Common issues
“Connection refused”
App listens on 127.0.0.1:8000 inside container; from host you get refused. Fix: app must bind 0.0.0.0.
“Address already in use”
Host port taken. Stop the conflicting container or pick another port.
DNS not resolving
You’re on the default bridge network. Move to a user-defined network.
Slow DNS
On Linux with systemd-resolved, container may use the host’s resolver. Add --dns 1.1.1.1 to bypass.
MACVLAN (container with real IP)
docker network create -d macvlan \
--subnet=192.168.1.0/24 \
--gateway=192.168.1.1 \
-o parent=eth0 \
publicnet
docker run --network publicnet --ip 192.168.1.50 nginx
Useful for legacy networking. Limitations: host can’t reach container by default (loopback isolation).
Overlay (Swarm / multi-host)
docker swarm init
docker network create -d overlay mynet
docker service create --network mynet --name web nginx
Containers across hosts can talk via the overlay network.
Reverse proxy + internal services
services:
proxy:
image: caddy
ports: ["80:80", "443:443"]
networks: [public, internal]
api:
build: .
networks: [internal]
worker:
build: .
networks: [internal]
networks:
public:
internal:
internal: true
Only proxy exposed publicly.
Common mistakes
- Using
localhostin container to reach another container —localhostis the container. - Hardcoded container IPs.
- Forgetting
--network mynet→ containers on different networks can’t talk. - Default bridge with multiple containers — no DNS by default.
- Publishing port without binding to interface in dev → exposed to LAN.
Read this next
If you want my network + reverse-proxy patterns, they’re at rajpoot.dev .
Building something AI-, backend-, or data-heavy and want a second pair of eyes? I do consulting and freelance work — see my projects and ways to reach me at rajpoot.dev .