What does starting a container with Docker's --network container:<name> flag do? Explain exactly what is shared and what is not shared between the two containers, and give a case where you would use it.
answer
- joins existing netns, does not create one
- shared: IP, interfaces, lo, ports, iptables
- not shared: filesystem, PID (unless --pid container:), cgroups
- -p rejected on joiner; owner publishes
- toolbox container on a distroless app; sidecar/VPN gateway
basics
~20 sThe new container joins the existing container's network namespace instead of getting its own. They share interfaces, IP, ports and loopback, so they reach each other on 127.0.0.1 and cannot both bind the same port. Filesystem, processes and users stay separate. It is the sidecar pattern, useful for debug and proxy containers.
solid answer
~50 s`--network container:web` puts the new container into the **same network namespace** as `web` rather than creating one. They then share one IP, one set of interfaces, one loopback and one port space: the sidecar can reach the app at `127.0.0.1:8080`, and if both try to bind 8080 the second fails. What is not shared: the mount namespace (separate filesystems and images), the PID namespace unless you also pass `--pid container:web`, user and IPC namespaces, and cgroup limits, which stay per-container. Publishing is decided by the owner: `-p` on the joining container is rejected, because the namespace already exists — ports must be published when the first container starts. Lifecycle is coupled: if the owning container stops, the namespace goes away and the joiner loses its network. My commonest use is debugging — attaching a netshoot-style toolbox container to a distroless app container to run tcpdump, ss or dig from inside its exact network view. It is also the mechanism behind sidecar proxies.
code
bash · 8 linesdocker run -d --name web -p 8080:8080 myapp:distroless
docker run --rm -it --network container:web \
--cap-add NET_ADMIN --cap-add NET_RAW \
nicolaka/netshoot ss -ltnp
# same namespace: this reaches the app over loopback
docker run --rm --network container:web curlimages/curl -s 127.0.0.1:8080/healthgo deeper
Recognise that the flag makes two containers share one network stack so they talk over localhost; the details are not expected.
Enumerate shared versus unshared namespaces accurately and note the single port space and the owner-publishes rule.
Lead with the debugging use on distroless images, cover lifecycle coupling and Compose's network_mode: service:x, and discuss the security implication of a sidecar that can rewrite the app's iptables.
Weigh namespace sharing against a shared network as a coupling decision, and connect it to the sidecar model an orchestrator will impose later.
## The mechanism A container's network stack is a Linux network namespace: its own interfaces, routing table, iptables rules, socket tables and loopback. Normally `docker run` creates a fresh one and wires a veth pair to a bridge. `--network container:web` skips creation and **enters the existing namespace** of the named container. The two processes now look, to the kernel network stack, like they are on the same machine. Concretely, they share: the IP address and MAC, all interfaces including `lo`, the routing table, the port/socket space, and any published port mappings. They do not share: filesystem (each still runs its own image with its own mounts), processes (separate PID namespaces unless you also pass `--pid container:web`), users, IPC, or resource limits — memory and CPU cgroups remain per-container, which is precisely what makes a sidecar independently limitable. ## Consequences that show up in practice **Localhost becomes the communication channel.** The sidecar talks to the app over `127.0.0.1`, which is fast and never leaves the host, and the app needs no configuration to accept it. This is exactly the model a Kubernetes pod generalises — containers in a pod share a network namespace for the same reason — though the pod abstraction itself belongs to orchestration, not to Docker. **Port conflicts are real.** One port space means two servers cannot both bind 8080. Sidecars must be assigned distinct ports. **Publishing belongs to the owner.** Because the namespace and its NAT rules were established when the first container started, `-p` on the joining container is refused. Any port a sidecar exposes must be published up front by the owning container, which is easy to forget when you add an exporter or proxy later. **Lifecycle coupling.** The joining container's network exists only as long as the owner does. Restart the owner and the joiner keeps running with a dead network stack; the practical rule is that the sidecar restarts with the app, and Compose users express it with `network_mode: "service:app"` plus `depends_on`. ## Where it earns its place *Debugging slim images.* Modern images are distroless or scratch-based, with no shell, no curl, no tcpdump. Attaching a toolbox container to the app's namespace gives you the app's exact network view — same interfaces, same DNS resolver, same conntrack — without adding tools to the production image. This is the single strongest argument for knowing the flag. *Sidecar proxies and adapters.* A TLS-terminating proxy, an authentication shim, or a metrics exporter that scrapes 127.0.0.1 all fit. Traffic interception via the sidecar's iptables rules also works because iptables state lives in the shared namespace. *VPN or egress gateways.* One container establishes a tunnel and other containers join its namespace so all their traffic exits through it, with no per-application configuration. ## Comparison with the alternatives Against a shared user-defined network, namespace sharing is tighter: same IP, loopback communication, no service discovery needed, but also no isolation between the two — a compromised sidecar sees and can manipulate the app's network stack, including binding ports and rewriting iptables. Against `--network host`, it is much narrower: the app's namespace is not the host's, so host services and host ports are still separate. The judgment call is coupling. Use it when two processes genuinely form one network endpoint or when you need someone else's exact network view; use a shared network when the containers are independent services that merely talk.
- Why is -p rejected on the container that joins another container's namespace?Port publishing is a property of the network namespace and its NAT rules, which were created when the owning container started. The joiner brings no new namespace, so there is nothing new to map. Any port the sidecar will listen on has to be published by the owner at its start time.
- How does this relate to a Kubernetes pod?A pod generalises the same primitive: its containers share one network namespace, so they see one IP and talk over localhost, which is why sidecars work there without configuration. Kubernetes creates the namespace via an infrastructure container rather than by pointing at a user container, and adds shared volumes and lifecycle management on top.
Two tenants sharing one apartment's phone line: same number and same doorbell, but separate rooms and separate belongings.
saying these in an interview costs you the question
- Claiming the containers share their filesystem or processes as well
- Expecting -p to work on the joining container
- Thinking two servers can both bind the same port in shared mode
- Confusing it with --network host, which joins the host's namespace
- Assuming the sidecar survives normally when the owning container stops