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¶
- Ad Blocking + Local DNS — both styles worked end-to-end
- Blog posts: PiHole + AdGuard in macvlans · on the bridge network