Chapter 7: Networking
Topic 44

Connecting Containers and Network Isolation

IsolationTopology

A container is not limited to one network. It can join several at once, and that is how you isolate tiers. A reverse proxy sits on a public-facing network and a backend network; the database sits only on the backend; nothing on the public network can reach the database, because they share no network. Isolation is a property of which networks a container is on — not an accident of which containers happen to coexist.

docker network connect and docker network disconnect attach and detach a running container without recreating it, so the topology is something you build and adjust deliberately. The default between two separate user-defined networks is that they cannot reach each other; you make connectivity, you do not have to prevent it.

Multiple Networks per Container

A container attached to several networks gets an interface and an IP on each, and resolves names on every network it shares. That is what lets one container bridge two otherwise-isolated tiers: it is the only thing on both, so it is the only path between them. Everything else on either network stays walled off from the other.

The Two-Tier Pattern

The pattern is two networks and a straddling container. A frontend network carries proxy and web; a backend network carries web and db. proxy is on frontend only; db is on backend only; web sits on both. Because proxy and db share no network, proxy can never open a connection to db directly — there is no route, no name resolution, nothing. The only way to the database is through web.

Two networks segment the tiers
frontend network
Carries proxy and web — the public-facing tier where requests arrive.
backend network
Carries web and db. The database is never on a public network, so proxy has no path to it.
A two-tier topology that keeps db unreachable from proxy
docker network create frontend
docker network create backend

docker run -d --name db    --network backend  postgres:16
docker run -d --name web   --network backend  driftwood:latest
docker network connect frontend web          # web now straddles both tiers
docker run -d --name proxy --network frontend -p 80:80 -p 443:443 nginx

web is created on backend so it can reach db, then docker network connect frontend web attaches it to frontend as well, so proxy can reach it. proxy and db never touch a shared network, which is the entire point of the layout.

Why db Is Segmented

Keeping db off any network that the public-facing proxy can reach means a compromise of proxy cannot open a connection to PostgreSQL. An attacker who lands inside proxy finds no route to db at all — they would first have to compromise web. This is defense in depth that publishing rules alone do not provide: not publishing db's port stops the outside world, but network segmentation stops a compromised peer too.

connect and disconnect at Runtime

docker network connect backend web attaches a running container to a network, and docker network disconnect backend web removes it — both without recreating the container or interrupting its other connections. That is useful for attaching a debug container to a network temporarily to poke at a service, or for migrating a container between networks during a change, rather than tearing it down and starting over.

Inspecting the Topology

docker network inspect backend lists which containers are attached and their addresses, and docker inspect db shows every network a container is on. Reading these is how you verify the isolation actually holds — that db really is on backend only, and that nothing public-facing has quietly been attached to it. Trust the inspect output, not your memory of which commands you ran.

Common Mistakes
  • Putting db on the same network as a public-facing proxy for convenience — a compromise of the proxy can now reach the database directly; segment the tiers so they share no network.
  • Assuming containers on different user-defined networks can reach each other — they cannot, unless a container straddles both; isolation between separate networks is the default, and it is the feature.
  • Attaching every container to one big network because it is simpler, losing the tier isolation a multi-network topology gives — that flat network is the default bridge's weakness reintroduced by hand.
  • Forgetting that a multi-homed container is reachable on every network it joined — attaching it to an extra network can unintentionally widen what can reach it.
Best Practices
  • Segment tiers onto separate user-defined networks so the database shares no network with anything public — db on a backend network, proxy on a frontend network, web bridging both.
  • Give each container only the networks it genuinely needs, since every attached network is another path to reach it.
  • Use docker network connect/disconnect to attach debug or migration containers temporarily rather than recreating the target.
  • Verify isolation with docker network inspect and docker inspect rather than assuming it — confirm db is on the backend network only.
Comparable tools Kubernetes NetworkPolicy expresses this isolation by rule, since all pods are mutually routable by default Podman supports the same multi-network attach and network connect/disconnect separate Linux bridges the isolation rests on distinct bridges and the absence of a route between them

Knowledge Check

What does attaching one container to multiple networks make possible?

  • That container can bridge two otherwise-isolated tiers, since it is the only thing on both networks
  • It merges the two separate networks into one flat shared network for all of their members
  • It gives the container a routable public IP that is reachable directly from the internet
  • It lets the container reach containers running on any other host in the wider cluster automatically

In the two-tier pattern, why can proxy never reach db directly?

  • They share no network — proxy is on frontend only, db on backend only, with only web on both
  • Because db publishes none of its own ports, which entirely blocks proxy from ever connecting to it
  • Because a firewall rule explicitly denies proxy access to the db address
  • Because db runs in host mode while proxy runs in ordinary bridge mode

What do docker network connect and disconnect do to a running container?

  • Attach or detach a network on the running container without recreating it
  • Stop the container, change its network membership, and start a fresh replacement copy
  • Add or remove the published host ports for the already-running container
  • Rebuild the container's image with the new network configuration baked in

Why do two separate user-defined networks isolate their members by default?

  • Each is its own bridge with no route between them, so members cannot reach across unless a container straddles both
  • Docker installs an explicit iptables deny rule between every possible pair of networks that you create
  • Traffic between the two networks is encrypted and members of each one lack the keys needed to decrypt it
  • Because all user-defined networks secretly share the one default bridge underneath, which then blocks cross-talk between them

You got correct