The container network model & drivers
CNM, bridge, host, macvlan, overlay.
Docker networking follows the Container Network Model (CNM): a container gets a network sandbox (its own network namespace), which attaches to one or more networks through endpoints, and a network driver implements each network. Which driver a network uses decides the container’s reachability and isolation, so the driver mental model is the thing to get straight — everything else is detail hanging off it.
bridge is the default: a private virtual network on one host with NAT out to the world. host removes the network namespace so the container shares the host’s interfaces — fastest, but no isolation and no port mapping. none gives no connectivity, for batch jobs that need none. overlay spans hosts (Swarm). macvlan gives the container its own MAC and IP on the physical network. Create your own bridge rather than the default, because a user-defined bridge adds DNS and isolation.
$ docker network create --driver bridge --subnet 172.30.0.0/24 appnet$ docker network lsNETWORK ID NAME DRIVER SCOPE1a2b3c4d5e6f appnet bridge local$ docker network inspect appnet -f '{{ .IPAM.Config }}'[{172.30.0.0/24 172.30.0.1 map[]}]
Scenario: isolate tiers with two networks
You want the web tier reachable from outside and the database reachable only from web — never directly. Put the database on a backend network only, and attach the web container to both a frontend and the backend network. A container can join multiple networks (docker network connect), and it can only reach services on networks it is attached to — so the database, absent from the frontend network, is simply unreachable from there.
$ docker network create frontend$ docker network create backend$ docker run -d --name db --network backend postgres:16 # backend only$ docker run -d --name web --network frontend -p 80:3000 myapp:1.0$ docker network connect backend web # web now on BOTH; can reach db# anything on frontend still cannot see db — it is not on that network
Scenario: a container that needs a real LAN address
A legacy service or a monitoring agent needs to appear as a first-class device on the physical network with its own IP, not hidden behind host NAT. macvlan attaches the container to the host’s physical interface and gives it its own MAC and IP on that subnet. It is powerful, but it requires the NIC in promiscuous mode, is frequently blocked on cloud provider networks, and by default the host itself cannot talk to its own macvlan containers.
$ docker network create -d macvlan \--subnet=192.168.1.0/24 --gateway=192.168.1.1 \-o parent=eth0 lan$ docker run -d --network lan --ip 192.168.1.50 --name probe nginx:1.27# probe now answers on 192.168.1.50 like any other box on the LAN