Container Networking Beyond Basics

Docker Intermediate/Advanced
Chapter 4 Β· Container Networking Beyond Basics

πŸ•ΈοΈ Container Networking Beyond Basics

Chapter 3 touched named networks in passing. This chapter explains the actual Docker networking model underneath every Compose file on this site β€” why service names "just work" as hostnames, and how to deliberately wall services off from each other.

Bridge Networks (the Default)

Bridge is Docker's default network driver β€” each container gets its own network namespace and IP on a virtual bridge. But there's a critical distinction between two kinds of bridge network:

  • The default bridge network (docker0) β€” containers can reach each other, but only by IP address. There's no automatic name-based DNS resolution on it at all.
  • A custom, user-defined bridge network β€” containers get automatic DNS resolution by container/service name, no IP address needed.

This is exactly why Compose always creates a custom network automatically for every project β€” it's the reason a service-name-based connection string like mysql://db:3306 works at all in every Compose example this site has used.

Host Networking

Host networking removes the network boundary entirely β€” a container shares the host machine's network namespace directly, binding to the host's ports with no mapping needed. The trade-off: maximum performance and simplicity, but zero network isolation β€” a real security consideration Chapter 6 covers properly. Rarely the right default choice.

Overlay Networks

Overlay networks answer "what about multiple physical/virtual hosts?" β€” they let containers running on different machines communicate as if they were on the same local network, the foundation multi-host orchestration (Docker Swarm, and conceptually Kubernetes) relies on. Chapter 8 covers orchestration properly; this is just naming where overlay networking fits in the bigger picture.

Custom Networks for Service Isolation

Multiple custom networks can deliberately segment which services can reach which β€” a genuine defense-in-depth technique, the same network-isolation principle dbsec1-4 applied at the VM/bare-metal level, just expressed at the container level instead.

networks: frontend: backend: services: web: networks: [frontend] api: networks: [frontend, backend] db: networks: [backend]

web can reach api (both on frontend), and api can reach db (both on backend) β€” but web has no network path to db at all, not merely "isn't supposed to" by convention. This is enforced at the network layer itself.

DNS-Based Service Discovery Between Containers

On a custom network, Docker's embedded DNS server resolves each container's service name directly to its current IP β€” no manual /etc/hosts editing, no hardcoded addresses that break the moment a container restarts with a new IP.

Default Bridge vs. Custom Bridge

Default Bridge

Containers can reach each other, but only by IP address β€” no built-in name resolution.

Custom Bridge

Automatic DNS by container/service name β€” exactly what makes mysql://db:3306-style connection strings work.

Network DriverUse Case
Default bridgeLegacy behavior; generally avoided in favor of custom bridges
Custom bridgeSingle-host multi-container apps β€” automatic DNS by name
HostMaximum performance, no isolation β€” rarely the right default
OverlayMulti-host communication (Swarm, conceptually Kubernetes)

πŸ’» Coding Challenges

Challenge 1: Explain Why a Service Name Resolves

Explain why mysql://db:3306 works as a connection string inside an api container in a Compose project, but wouldn't work between two containers started with plain docker run on the default bridge network.

Goal: Practice connecting Compose's automatic custom-network creation to the DNS resolution it enables.

β†’ Solution

Challenge 2: Design an Isolated Network Layout

Design a Compose network layout for a system with a public-facing web service, an internal api service, and a db service, such that web can never reach db directly.

Goal: Practice applying the frontend/backend network-segmentation pattern to a new scenario.

β†’ Solution

Challenge 3: Diagnose a Connection Failure

A developer's web service can't reach their db service at all, even though both containers are "running." Using this chapter's material, list the most likely cause.

Goal: Practice recognizing network segmentation as the likely cause of an otherwise-confusing connection failure.

β†’ Solution

⚠️ Gotcha: "Both Running" Doesn't Mean "Can Reach Each Other"

It's a common early confusion to assume two containers can talk to each other simply because both show as running in docker ps. If they're on different networks β€” or one is on the default bridge while the other is on a custom network β€” there is genuinely no network path between them at all, not a permissions issue, not a firewall rule, just no route. This isn't a bug; it's the isolation feature working exactly as designed, the same isolation this chapter's frontend/backend example deliberately relied on. When two containers can't reach each other, checking which networks each one is actually attached to (docker network inspect) is one of the first things worth verifying, before assuming the problem lies somewhere else entirely.

🎯 What's Next

The next chapter is Volumes & Data Management in Production β€” named volumes vs. bind mounts vs. tmpfs, backup strategies for containerized data, and volume drivers.