Skip to content

Docker Networking

TL;DR / when to use this: The two networks I use most on the home server are bridge (default, simple, port mappings required) and macvlan (container gets its own LAN IP like a physical device). Choose macvlan when a container must be addressable on the LAN as its own host (DNS servers, devices expecting a LAN IP); choose bridge otherwise.

Bridge

  • Default Docker network.
  • Container shares the host IP; services are exposed via port mappings (53:53, 8080:8080, ...).
  • Host ↔ container communication works out of the box.
  • Only one container can bind a given host port — so two DNS servers can't both own 53 on bridge.

Macvlan

  • Attaches the container to a parent interface (driver_opts: parent: eno1) with its own IP on the LAN subnet.
  • No port mappings needed — everything the container listens on is exposed directly.
  • Multiple containers can run the same service simultaneously (AdGuard at .100, Pi-hole at .101).
  • Gotcha: the host cannot talk to macvlan containers by default. LAN clients can, but the host can't — which breaks the host using its own DNS. Fix with a bridge-mode macvlan link + routes:
sudo ip link add macvlan0 link eno1 type macvlan mode bridge
sudo ip addr add 192.168.4.254/24 dev macvlan0
sudo ip link set macvlan0 up
sudo ip route add 192.168.4.100 dev macvlan0

Persist with a systemd oneshot service (see Ad Blocking).

Quick comparison

Bridge Macvlan
Container IP Host IP + mapped ports Own LAN IP
Host ↔ container Works by default Needs manual link + routes
Same service twice Port conflict Fine — separate IPs
Complexity Low Medium (persistence, parent interface)

See also