Connect Containers with Default Bridge
Learn how to connect containers using the default bridge network in Docker. This lesson covers the core concepts, step-by-step setup, hands-on exercises, and troubleshooting tips for leveraging Docker's default bridge network to enable container communication.
Focus: connect containers with default bridge network
You've built your first Docker image, maybe even launched a few isolated containers. But a single container is just an island. The real power of Docker emerges when you connect containers together — for example, a web server talking to a database, or a microservice calling an API. Without a network, containers are blind to each other. The default bridge network is Docker's built-in, zero-config solution to let containers communicate by container name, solving the exact isolation pain that arises when you need two containers to talk on the same host.
The problem this lesson solves
Imagine you have a Node.js app container that needs to write to a PostgreSQL database container. You start both containers with docker run. They're both running, but the Node app can't reach localhost:5432 because that refers to its own container, not the database. The database isn't on the same network, so ping or curl fails. This is the fundamental challenge: containers are isolated by default. The default bridge network gives them a shared virtual LAN segment so they can discover each other by name and exchange data securely — without opening ports to the outside world.
Core concept / mental model
Think of Docker's default bridge network as a virtual switch inside your computer. Every container attached to it gets a private IP address (typically in the 172.17.0.0/16 range) and can talk to other containers on the same bridge using those IPs — or, more conveniently, using container names as hostnames.
💡 Pro Tip: The default bridge is created automatically when Docker Engine starts. It's named
bridgeand you can inspect it withdocker network inspect bridge.
Key properties
- Automatic: No
docker network createneeded — it's there out of the box. - Name resolution: While containers connected to the default bridge can communicate by IP, Docker's embedded DNS does not resolve container names on the default bridge for automatic discovery. You must use
--link(deprecated) or better — attach containers to the same user-defined bridge. However, this lesson focuses on the default bridge, where you rely on IPs or published ports for connectivity.
Wait — this is a common point of confusion. Let's clarify: on the default bridge, containers can ping each other by IP, but not by container name automatically. This is a key limitation that we'll address in the Compare section. For now, understand that the default bridge is the simplest path to get two containers talking.
How it works step by step
- Docker Engine starts — creates the default bridge network named
bridge. - You run a container without specifying
--network— Docker attaches it to thebridgenetwork by default. - Each container gets a virtual Ethernet interface — an IP address from the bridge's subnet (e.g.,
172.17.0.2). - Containers can reach each other — using those IPs, or by publishing ports to the host.
- The host acts as a gateway — the
docker0interface (IP172.17.0.1) forwards traffic between containers and the outside world.
Communication flow
Container A (web) → 172.17.0.2:5000
Container B (db) → 172.17.0.3:5432
Gate: 172.17.0.1 (host machine)
When Container A sends a packet to 172.17.0.3:5432, it goes out its virtual eth0 to the docker0 bridge, which forwards it to Container B's eth0. No external network needed.
Hands-on walkthrough
Let's make two containers talk. We'll use alpine for simplicity — one acts as a server, the other as a client.
Step 1: Start a container that listens
docker run -dit --name server alpine sh -c "while true; do echo 'Hello from server'; sleep 2; done"
Step 2: Get the server's IP on the default bridge
docker inspect server | grep IPAddress
# Output: "IPAddress": "172.17.0.2"
Step 3: Start a client container and ping the server by IP
docker run -it --name client alpine sh -c "ping -c 4 172.17.0.2"
You'll see successful replies:
PING 172.17.0.2 (172.17.0.2): 56 data bytes
64 bytes from 172.17.0.2: seq=0 ttl=64 time=0.123 ms
64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.089 ms
Step 4: Try using the container name (fails on default bridge)
docker run -it --name client2 alpine sh -c "ping -c 2 server"
Expected output:
ping: bad address 'server'
Step 5: Use --link (deprecated but works on default bridge)
docker run -it --name client3 --link server alpine sh -c "ping -c 2 server"
Now it resolves. But --link is legacy — for production, use user-defined networks.
Compare options / when to choose what
| Feature | Default Bridge | User-Defined Bridge | Host Network |
|---|---|---|---|
| Automatic DNS | ❌ (no name resolution by default) | ✅ (container names resolve) | N/A |
| Isolation from host | ✅ | ✅ | ❌ (shares host net) |
| Port publishing | ✅ (-p) |
✅ (-p) |
Direct port access |
| Container naming | Manual IPs or --link |
Automatic discovery | Host DNS |
| Recommended for | Quick tests, single host | Multi-container apps, dev | Performance-critical, low latency |
When to choose the default bridge:
- You just need two containers to communicate quickly for a one-off test.
- You're following a simple tutorial and want minimal setup.
- You're aware of the IP resolution limitation and are okay with using IPs or --link.
When to upgrade to a user-defined bridge: - You want automatic DNS resolution by container name. - You plan to detach and reattach containers (default bridge doesn't re-link IPs). - You need better isolation with your own subnet.
Troubleshooting & edge cases
Containers can't ping each other
- Check both are on the same network:
docker inspect <container> | grep NetworkMode. If one is onhostand the other onbridge, they won't talk. - Firewall or iptables: Docker adds iptables rules, but custom rules might block inter-container traffic. Run
iptables -L -nto inspect. - IP change after restart: On the default bridge, IPs can change when containers restart. Always rely on IPs obtained fresh from
docker inspector move to user-defined networks.
"Cannot connect to the Docker daemon"
- Ensure Docker Engine is running:
systemctl status docker(Linux) or check Docker Desktop.
Port publishing conflicts
- If two containers need the same host port (e.g., both want
-p 80:80), only one can bind. Use different host ports like-p 8080:80.
What you learned & what's next
You now understand: - How the default bridge network lets containers communicate by IP. - The step-by-step process to create and test container-to-container connections. - The limitations of the default bridge (no automatic DNS) compared to user-defined networks. - How to troubleshoot common pitfalls.
Next step: Learn to create a user-defined bridge network — which gives you automatic DNS resolution, better isolation, and the ability to attach/detach containers dynamically. This is what you'll use in real multi-service applications.
Practice recap
Start two containers on the default bridge: a simple HTTP server (using nginx or python -m http.server) and a client (e.g., alpine with wget). Verify they can exchange data by using the server container's IP. Then attempt to use the container name — see the failure, and understand why user-defined networks are the next step.
Common mistakes
- Assuming container names resolve to IPs on the default bridge — they don't. Use
--link(deprecated) or find the IP viadocker inspect. - Forgetting that containers must be on the same network to communicate. If one container is on
hostnetwork and another onbridge, they can't reach each other without publishing ports. - Using
localhostinside a container to talk to another container.localhostrefers to the container's own network stack. Use the other container's IP or published host port. - Not checking if Docker's iptables rules are intact. Custom firewall configurations can block inter-container traffic silently.
Variations
- Use
docker run --network bridgeexplicitly to emphasize the network, though it's the default. - Use a user-defined bridge network for automatic DNS resolution:
docker network create mynet && docker run --network mynet .... - Use the
hostnetwork driver to skip network isolation when performance is critical (but be aware of security trade-offs).
Real-world use cases
- A web server container communicating with a PostgreSQL database container on the same host for local development.
- A Redis cache container serving multiple app containers on the default bridge during a quick prototype or spike.
- A monitoring agent container (e.g., Prometheus node exporter) scraping metrics from an application container on the same bridge network.
Key takeaways
- Containers on the default bridge can communicate by IP but not by container name automatically.
- Use
docker inspect <container> | grep IPAddressto find a container's IP for inter-container communication. - The default bridge is ready out of the box — no
docker network createneeded. --linkis a legacy workaround for name resolution on the default bridge; prefer user-defined networks for production.- Port publishing (
-p) is the only way to expose a container to the host or outside world from the default bridge. - Always verify network membership with
docker inspectwhen troubleshooting connectivity issues.
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.