Docker Network Drivers Beyond Bridge
Bridge is the default, not the only option. What host, none, macvlan and overlay actually do, when each is the right answer, and the isolation you give up choosing them.
Storage and Networking Guide 11 of 46 Intermediate
- OSUbuntu 26.04 LTS (resolute)
- Docker Engine29.7.2
- Shellbash
- Architectureamd64
- TimeAbout 12 min
- Reviewed20 August 2026
Tested on the versions above. Interface names and addresses are specific to the capture host. Overlay could not be demonstrated here - it requires swarm mode, and the refusal is shown rather than a fabricated success.
| Server Name | IP Address | OS | Roles | CPU | RAM | HDD |
|---|---|---|---|---|---|---|
| DOCKER01 | 192.168.0.21 | Ubuntu 26.04 LTS | Docker Host | 2 Core | 4 GB | 50 GB |
Before you start
-
What is available
The daemon ships several drivers and the built-in networks show three of them.
bridgeis the default for every container you have run so far.hostandnoneare the two extremes - all of the host's networking, or none at all.bash Example session docker network lsNETWORK ID NAME DRIVER SCOPE0feece5f4df1 bridge bridge local10048ac8b69a host host local9403714e56ad none null localExpected resultThe three built-in networks, which cannot be removed.
Success conditionYou can see the drivers by name.
docker info --format "{{json .Plugins.Network}}"lists every driver the daemon supports. -
none: no networking at all
A container on
nonegets a loopback interface and nothing else. No address, no route, no DNS. This is the right choice for a job that only processes mounted files - a batch converter, a backup task - and it removes network attack surface completely.bash Example session docker run --rm --network none alpine:3.22 ip -o addr show1: lo inet 127.0.0.1/8 scope host lo1: lo inet6 ::1/128 scope hostdocker run --rm --network none alpine:3.22 wget -qO- --timeout=3 http://example.comwget: bad address 'example.com'Expected resultOnly
lo, and any outbound request failing.Success conditionNo eth0 exists. Compare with
--internalfrom the previous guide: internal still lets containers talk to each other,nonedoes not give the container a network at all. -
host: the container uses the host's network stack directly
With
--network hostthere is no network namespace and no virtual interface - the container sees exactly the host's interfaces, including the addresses. The output below is identical to running the command on the host itself.bash Example session ip -o -4 addr show scope global | head -22: eth0 inet 192.168.0.23/24 brd 192.168.0.255 scope global eth03: docker0 inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0docker run --rm --network host alpine:3.22 ip -o -4 addr show scope global | head -22: eth0 inet 192.168.0.23/24 brd 192.168.0.255 scope global eth03: docker0 inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0Expected resultByte-identical interface lists from inside and outside.
Success conditionThe container has the host's addresses. That is not a shortcut to bridge networking - it is the absence of network isolation.
-
What host mode changes about ports
Because there is no separate network namespace, there is nothing to publish. The service binds the host's port directly and
-pis meaningless - Docker records no port mappings at all. Useful for a service that must see real client IPs or open many ports; a poor default, because two such containers cannot share a port and neither is isolated from the host.bash Example session # note: no -p flag anywheredocker run -d --name cg-hostnet --network host nginx:alpinecurl -s -o /dev/null -w "%{http_code}" http://localhost:80200docker port cg-hostnet# no output - nothing is published, yet it is servingExpected resultA serving container with an empty port map.
Verify it worked
bash Example session docker inspect cg-hostnet --format "netmode={{.HostConfig.NetworkMode}} ports={{.NetworkSettings.Ports}}"netmode=host ports=map[]docker rm -f cg-hostnetSuccess conditionYou understand why
-pand--network hostdo not combine. Docker warns and ignores the flag. -
macvlan: a container with its own address on your LAN
macvlan gives the container a MAC address of its own on a physical interface, so it appears on the network as a separate machine with a real LAN address. This is for legacy systems that expect a host on the network rather than a proxied port. It needs a parent interface, and getting that wrong is the usual failure.
bash Example session docker network create -d macvlan --subnet 192.168.0.0/24 --gateway 192.168.0.1 -o parent=eth0 cg-mv8b519b65fc4a20a70fae2aeb9116174c33ba65eb3b4c006d73a4f068131a03d2docker network inspect cg-mv --format "driver={{.Driver}} subnet={{range .IPAM.Config}}{{.Subnet}}{{end}}"driver=macvlan subnet=192.168.0.0/24# no container was attached here: it would take a real address on the LANdocker network rm cg-mvExpected resultThe network created against a real parent interface, then removed.
Success conditionThe driver is macvlan and the subnet matches your LAN. Before attaching anything, reserve an address range your DHCP server will not hand out, or you will get a duplicate-address conflict.
-
overlay: multi-host, and it needs an orchestrator
overlay connects containers across several machines, and it is not available to a standalone daemon - it belongs to swarm mode. Attempting it on an ordinary host fails with a message that names the requirement. This guide does not enable swarm, because that changes the machine's role rather than running a container.
bash docker network create -d overlay cg-ovlError response from daemon: This node is not a swarm manager. Use "docker swarm init" or "docker swarm join" to connect this node to swarm and try again.# multi-host networking is an orchestration feature - in practice Kubernetes or swarmExpected resultA clear refusal naming swarm mode.
Success conditionYou know where single-host Docker stops. If you need containers on several machines to share a network, you are choosing an orchestrator, not a driver.
-
Choosing
In order of how often they are the right answer: user-defined bridge for almost everything; none for a job with no network needs; host when you genuinely need the host's stack and accept losing isolation; macvlan when something outside must treat the container as a machine; overlay only with an orchestrator.
bash bridge default, isolated, DNS by service name <- start herenone no network at allhost no network isolation from the hostmacvlan real address on the physical LANoverlay multi-host, swarm or Kubernetes onlydocker network inspect NAME --format "{{.Driver}}"Expected resultA decision you can defend.
Success conditionYou reach for host mode as a deliberate exception rather than a fix for a bridge problem you have not diagnosed.
Troubleshooting
Published ports are ignored with a warning
Why:
-pwith--network hostdoes nothing - there is no namespace to forward from.Fix:Drop the
-pand have the service bind the port it should listen on. If you need mapping, use bridge.bash docker inspect NAME --format "{{.HostConfig.NetworkMode}}"macvlan containers cannot reach the host, or the host cannot reach them
Why: Expected behaviour. A macvlan child interface cannot talk to its own parent - the packets never leave the NIC.
Fix:Create an additional macvlan interface on the host itself for that path, or put the container on a second bridge network for host-facing traffic.
bash docker network connect bridge NAMEinvalid subinterface vlan name
Why: The
parent=option does not name a real interface on the host. It must be an existing NIC, or an existing VLAN subinterface iniface.vlanform.Fix:List the host's interfaces and use the actual name.
bash ip -o link showHost-mode container conflicts with a service on the host
Why: There is one port space now. The container competes with the host's own daemons for it.
Fix:Check the port is free before starting, or use bridge with a mapping so the host side can differ.
bash ss -ltnp | grep :80