docker network create and Compose's networks: both default to a bridge network without asking, which is exactly why most people never have to think about network drivers at all — until a Dockerfile or Swarm setup does something different and the container can't reach anything it used to. Docker ships five built-in drivers; three of them (bridge, host, overlay) cover the vast majority of real setups, and the other two (macvlan, ipvlan) exist for a narrower, more specialized reason.
| Driver | Scope | Isolation | Typical use |
|---|---|---|---|
| bridge | Single host | Isolated, NAT'd to the host | The default — most containers on one machine |
| host | Single host | None — shares the host's network stack | Max throughput, or a process that needs the real host network |
| overlay | Multi-host (Swarm) | Isolated, tunneled between nodes | Services spread across a Swarm cluster |
| macvlan | Single host, physical LAN | Isolated — each container is its own MAC on the wire | Legacy apps that expect a real NIC |
| ipvlan | Single host, physical LAN | Isolated — containers share one MAC, own IPs | Same as macvlan, where the switch caps MACs per port |
bridge: isolated, NAT'd, and the only one with two personalities
Every Docker install has a network literally named bridge — the default bridge — and a bare docker run with no --network flag lands on it. It has no built-in DNS between containers; they can only reach each other by IP. A user-defined bridge — anything you create with docker network create, or that Compose creates for you — is the same driver, but gets Docker's embedded DNS server, so containers resolve each other by name. This distinction, and exactly how that DNS server works, is covered in full in How Docker DNS Resolution Works; the network-membership rules (which containers can reach which) are covered in Understanding Docker Networks.
Same driver, same NAT'd isolation from the host — the only difference is whether Docker's embedded DNS server is running.
host: no isolation, no port mapping, no DNS
network_mode: host (or docker run --network host) puts the container directly on the host's own network namespace. The process inside binds host ports directly — no -p mapping, no NAT, no container-specific IP — the same as if it ran outside a container entirely. That also means no isolation and no per-container DNS: it uses whatever /etc/resolv.conf the host itself uses.
It's effectively Linux-only in practice: Docker Desktop on Mac and Windows runs the daemon inside a lightweight VM, so host mode there puts a container on that VM's network, not your actual machine's — a common source of "host mode isn't working" confusion for anyone testing on a Mac before deploying to Linux. Worth knowing before relying on it: a ports: entry alongside network_mode: host in a Compose file isn't rejected — Compose accepts it silently, and it just does nothing, since host mode bypasses Docker's port-publishing path entirely.
overlay: the only one built for multiple hosts
overlay connects containers running on different Docker hosts as if they were on one network, tunneling traffic between nodes with VXLAN. The catch: it always requires Swarm mode, even to connect two plain standalone containers with no Swarm services involved at all — Docker's own docs are explicit that hosts "must be part of a swarm to use overlay networks, even when connecting standalone containers." A standalone container can join one only if it was created with the --attachable flag.
Three port ranges have to stay open between every node for it to work at all:
| Port | Purpose |
|---|---|
2377/tcp | Swarm control plane |
7946/tcp + 7946/udp | Node-to-node discovery (not configurable) |
4789/udp | Overlay data traffic (VXLAN) |
Both nodes attach to the same overlay network; api reaches db by name across the VXLAN tunnel, same as if they shared a single-host bridge network.
macvlan and ipvlan: the two you'll rarely reach for
Both put containers directly on the physical LAN instead of behind Docker's NAT, and both are Linux-only, incompatible with most cloud providers' networking, and unsupported on Docker Desktop. macvlan gives every container its own MAC address, so it appears on the network as a distinct physical device — the switch has to allow promiscuous mode, and containers on a macvlan network can't reach the host itself directly, a real Linux kernel restriction, not a config gap. ipvlan solves a specific problem this creates: switches that cap how many MAC addresses one physical port can register. Every ipvlan container shares the parent interface's single MAC address and gets distinguished by IP instead. Reach for either only when a legacy app or monitoring tool genuinely needs to look like it's wired directly into the LAN — bridge or overlay covers everything else.
Try it yourself
Docker Network Inspector reads real docker network inspect output and identifies exactly which of these five drivers a network is using, plus what that driver implies — including flagging a default bridge network being relied on for name resolution. For the Compose side, Docker Compose Visualizer shows which services actually share a network before you run anything, and Docker Compose Validator catches a network reference that was never declared. All three run entirely in your browser.