Manage Docker Networks
Learn to manage default bridge, custom bridges, and overlay networks in Docker. This lesson covers creating, connecting, and inspecting networks for container isolation and communication.
Focus: manage docker networks basics
You've built Docker images, run containers, and maybe even volume-mounted your code. But put two containers on the same host and they can't talk to each other — unless you understand Docker networking. Out of the box, every container gets an IP, but how they find each other, whether they're isolated, and how they reach the outside world depends entirely on the network you attach them to. This lesson gives you the mental model and the CLI commands to manage Docker networks basics with confidence.
The problem this lesson solves
When you run docker run nginx, Docker automatically creates a 'bridge' network, the default bridge called bridge (older systems) or docker0. That sounds helpful — and it is — but the default bridge has limits:
- Containers on the default bridge can only communicate by IP address, not by container name.
- There is no built-in DNS that resolves container names to IPs.
- All containers on the default bridge can talk to each other, which is often too permissive.
- You have no control over subnet or IP range.
As soon as your project involves multiple services — a web server and a database, or a microservice with a message queue — you need custom networks to enable clean, predictable communication. That's the problem: default networking is a trap for the unwary, and manual IP management is fragile.
Core concept / mental model
Think of a Docker network as a virtual switch or a virtual LAN (VLAN). Containers plugged into the same virtual switch can see each other. Containers on different virtual switches are completely isolated unless you explicitly connect them.
Key definitions
- Bridge network (default): A private internal network on your host. Containers attached to the same bridge can communicate. The default bridge (
docker0) uses NAT to allow outbound traffic to the host and internet, but inbound traffic isn't forwarded from the outside. - Host network: The container shares the host's network stack — no network isolation, full performance, but risky.
- Overlay network: Spans multiple Docker hosts (nodes) in a swarm. Containers on different hosts can communicate as if they were on the same virtual switch.
- Macvlan / IPvlan: Assign a MAC/IP from the physical network directly to the container — useful for legacy apps that expect to be on the same subnet.
Pro tip: For most multi‑container apps, a user‑defined bridge network is the sweet spot: automatic DNS resolution, isolation, and clean IP management.
How it works step by step
-
Create a custom bridge network
docker network create my-netThis creates a new bridge network with a private subnet (typically172.x.0.0/16). Docker also creates a DNS resolver that maps container names to their IPs. -
Start containers on that network
docker run -d --name web --network my-net nginxThe container gets an IP withinmy-net's subnet. Docker registers the container name 'web' in the network's DNS. -
Connect a second container
docker run -d --name db --network my-net postgresNowwebcan reachdbusing the hostnamedb(orwebfromdb). No IP hunting. -
Connect an existing container If a container already exists on the default bridge, you can attach it to your custom network without restarting:
docker network connect my-net existing-containerThe container now has two interfaces: one on the default bridge, one onmy-net. -
Disconnect a container
docker network disconnect my-net existing-containerRemoves the interface from that network. -
Inspect networks
docker network inspect my-netshows all containers attached, subnet, gateway, and more.
Hands-on walkthrough
Let's build a realistic scenario: a Flask web app talking to a Redis cache. Both must communicate securely and predictably.
Step 1: Create a custom bridge network
docker network create app-net
Expected output (your ID will differ):
7a3f9b2c1d0e...
Step 2: Run Redis on app-net
docker run -d --name redis-cache --network app-net redis:alpine
Check that it's running:
docker ps --filter name=redis-cache
Step 3: Run a simple Python app on the same network
# app.py
import redis
import time
cache = redis.Redis(host='redis-cache', port=6379, decode_responses=True)
cache.set('visits', 1)
print(f"Visits: {cache.get('visits')}")
# Build and run the container
docker run -d --name web-app \
--network app-net \
-v $(pwd):/app \
python:3.10-slim \
python /app/app.py
Check the logs:
docker logs web-app
# Output: Visits: 1
Step 4: Connect a container to multiple networks
Sometimes you need a container that is both on a backend network (for databases) and a frontend network (for reverse proxy). Create a second network and connect:
docker network create frontend-net
docker network connect frontend-net web-app
Now web-app has two IPs and can communicate with containers on both networks.
docker inspect web-app --format '{{range .NetworkSettings.Networks}}{{.IPAddress}} {{end}}'
# Output: 172.18.0.3 172.19.0.2 (different IP for each network)
Pro tip: Use
docker network lsto list all networks. Usedocker network pruneto delete unused networks, but be careful — it removes all networks not used by at least one container.
Compare options / when to choose what
| Network type | Use case | DNS resolution | Isolation | Performance |
|---|---|---|---|---|
Default bridge (docker0) |
Quick dev / single container | By IP only | Low (all containers) | Good |
| User‑defined bridge | Multi‑service app (web+db) | By container name | High (per network) | Good |
host |
Performance‑sensitive apps (e.g., benchmarks) | N/A (uses host) | None | Best |
overlay |
Multi‑host swarm services | Built‑in | Moderate | Medium (encrypted) |
macvlan |
Legacy apps needing same subnet as host | External DHCP | Low | Good |
Rule of thumb: Start with a user‑defined bridge for any project with more than one container. Only switch to host or macvlan when you have a concrete need.
Troubleshooting & edge cases
Container can't reach another by name
- Symptom:
ping other-containerfails. - Cause: The container is on the default bridge, which has no automatic DNS.
- Fix: Create a user‑defined network and attach both containers to it.
Two containers can't communicate even on the same network
- Check:
docker network inspect <network>to verify both are listed. If a container shows no IP, it may be misconfigured. - Fix: Disconnect and reconnect:
docker network disconnect <net> <container>thendocker network connect.
Port already allocated (binding conflict)
- Symptom:
docker: Error response from daemon: driver failed programming external connectivity... - Cause: Another container or host process is already listening on that port.
- Fix: Use a different host port (e.g.,
-p 8080:80instead of-p 80:80) or stop the conflicting container first.
Containers on different user‑defined bridges can't talk
- This is by design — they are isolated.
- Solution: Create a common network and connect both containers to it, or use a reverse proxy (like Traefik / Nginx) as a router.
docker network prune removed a network you needed
- Prevention: A network is pruned only if no container is attached to it. If one container is stopped but still referenced, the network survives. Use
docker network ls --filter dangling=trueto preview.
What you learned & what's next
You now understand the three core Docker network modes (bridge, host, overlay) and how to:
- Create custom bridge networks (
docker network create) - Attach containers at start or on the fly (
--network,docker network connect) - Inspect network topology (
docker network inspect,docker inspectwith format) - Compare when to choose each type
- Troubleshoot common connectivity issues
These skills are the foundation for running multi‑service applications, which is exactly where Docker Compose shines. In the next lesson, you'll learn how to define all your services, networks, and volumes in a single docker-compose.yml file — no more typing long docker run commands. You'll also see how Compose automates network creation with DNS resolution out of the box.
Ready to simplify your workflow? Let's go.
Practice recap
Create a Docker network called practice-net, then run an nginx container and a busybox container on it. From the busybox container, run wget -O- http://nginx — you should get the Nginx welcome page. If it works, you've successfully set up container‑to‑container communication by name.
Common mistakes
- Using the default bridge for multi‑container apps and then trying to reach containers by name — it only works with IPs on that network.
- Forgetting to specify
--networkondocker run— the container ends up on the default bridge, isolated from your custom network. - Running
docker network prunewithout checking, accidentally removing a network that had stopped containers still referenced. - Assuming containers on different user‑defined bridges can talk — they can't unless you explicitly connect them or use a shared network.
- Not inspecting
docker network inspectwhen debugging — the output shows IPs and connected containers, but many skip it.
Variations
- Use
docker composeinstead of rawdocker networkcommands — Compose creates a default network per project and handles DNS resolution automatically. - For production multi‑host setups, consider
overlaynetworks with Docker Swarm or Kubernetes network policies instead of manual bridge management. - Use
docker network create --driver overlay --attachable my-overlayto create an overlay network that non‑swarm containers can also connect to.
Real-world use cases
- Web app with PostgreSQL: web container on a custom bridge network, DB on the same — secure, name‑based communication.
- Microservices with a message bus: three services (auth, orders, notifications) each on a private bridge, sharing a common 'internal' network for the bus.
- Legacy app needing direct LAN access: use macvlan to give the container an IP from the physical subnet, avoiding port mapping.
Key takeaways
- Custom bridge networks provide automatic DNS resolution — use them instead of the default bridge for any multi‑container app.
- Containers on different networks are isolated; connect them explicitly with
docker network connector a shared network. docker network inspectis your best friend for debugging connectivity — it shows IPs, DNS, and attached containers.docker network pruneis dangerous in shared environments — preview withdocker network ls --filter dangling=truefirst.- Host and macvlan networks are for specialized needs (performance, legacy); user‑defined bridges handle 95% of real‑world scenarios.
Keep learning
Related tutorials, quizzes, and articles for this topic.
Discussion
Questions, corrections, and tips help everyone reading this page.
0 comments
Add a comment
No comments yet — start the thread.