CertGrid CertGrid
Concepts·Docker

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

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.

One Docker host is all this guide needs. Nothing here depends on a second machine, and the hardware above is modest on purpose - a 2 core, 4 GB VM runs everything in this path.
Server NameIP AddressOSRolesCPURAMHDD
DOCKER01192.168.0.21Ubuntu 26.04 LTSDocker Host2 Core4 GB50 GB

Before you start

  1. What is available

    The daemon ships several drivers and the built-in networks show three of them. bridge is the default for every container you have run so far. host and none are 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      local

    Expected 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.

  2. none: no networking at all

    A container on none gets 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 --internal from the previous guide: internal still lets containers talk to each other, none does not give the container a network at all.

  3. host: the container uses the host's network stack directly

    With --network host there 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 docker0

    Expected 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.

  4. 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 -p is 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 serving

    Expected 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-hostnet

    Success conditionYou understand why -p and --network host do not combine. Docker warns and ignores the flag.

  5. 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-mv

    Expected 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.

  6. 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 swarm

    Expected 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.

  7. 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

Official sources