Containers on your real LAN via DHCP: IPv4+IPv6, macvlan/ipvlan/bridge, VLAN, APIPA failsafe
9.9K
Linux Docker managed plugin that connects containers to your existing LAN
and lets your real DHCP server (router, Dnsmasq, Kea, ISC, UniFi, …) hand
out their addresses — IPv4 and IPv6. Containers appear on the network as
first-class LAN clients, with their own MAC, DHCP lease, hostname registration
and router visibility. The DHCP client is Go-native (no udhcpc, no CGO), and
all privileged network setup is done by the plugin — workload containers need
zero capabilities.
| Tag | Channel | Meaning |
|---|---|---|
latest, stable | stable | stable code from the main branch (latest is what untagged installs resolve to) |
vX.Y.Z | release | immutable versioned launches |
release | release | always the newest version |
dev | dev | code in progress (still test-gated before publishing) |
<sha8> | — | immutable pin for any published build |
Multi-arch: linux/amd64, linux/arm64.
bridge, macvlan (bridge/private), ipvlan
(l2/l3), with automatic 802.1Q VLAN sub-interfaces (-o vlan=N).169.254.0.0/16 address and the plugin keeps
soliciting; the real lease is swapped in the moment a server responds.-o dhcpv6=true).resolv.conf; the container hostname is sent as DHCP option 12 so
routers register the lease by name.--mac-address plus a server-side reservation for a fixed IP./healthz with per-endpoint lease/phase detail,
Prometheus /metrics, structured JSON logs, and rich
docker network inspect endpoint info.runc;
keep default-runtime: runc — workloads may still opt into other runtimes).--grant-all-permissions).sudo mkdir -p /var/lib/docker-net-dhcp
docker plugin install fernandodelucca/docker-net-dhcp:latest \
--alias docker-net-dhcp \
--grant-all-permissions
docker plugin ls # docker-net-dhcp ENABLED true
Upgrade without losing endpoints (leases are restored by the new process):
docker plugin disable docker-net-dhcp
docker plugin upgrade docker-net-dhcp --grant-all-permissions
docker plugin enable docker-net-dhcp
Containers directly on the LAN via macvlan, addresses from your DHCP server (Mode A — resilient default; note the tag in the driver name):
docker network create \
--driver docker-net-dhcp:latest --ipam-driver null \
-o bridge=eth0 -o mode=macvlan \
lan
docker run -d --network lan --hostname web-01 \
--mac-address 02:42:ac:11:00:05 nginx
docker exec <id> ip addr show eth0 # inet 192.168.1.x/24 from your server
Dual-stack (IPv4 + SLAAC IPv6) on a tagged VLAN — pass both --ipv6
(Docker) and -o ipv6=true (plugin):
docker network create \
--driver docker-net-dhcp:latest --ipam-driver null --ipv6 \
-o bridge=eth0 -o mode=macvlan -o vlan=50 \
-o ipv6=true -o require_mac=true \
lan-v6
Compose:
services:
web:
image: nginx
hostname: web
networks:
lan:
mac_address: "02:42:ac:11:00:05" # fixes the DHCP reservation AND the IPv6 identity
networks:
lan:
driver: docker-net-dhcp:latest
driver_opts:
bridge: eth0
mode: macvlan
require_mac: "true"
ipam:
driver: "null" # Mode A — DHCP handles addressing
-o key=value)| Option | Default | Meaning |
|---|---|---|
bridge | required | Existing Linux bridge or parent NIC |
mode | bridge | bridge, macvlan or ipvlan |
macvlan_mode | bridge | bridge or private |
ipvlan_mode | l2 | l2 or l3 |
vlan | 0 | 0–4094; creates parent.N for macvlan/ipvlan |
mtu | 0 | 0 inherits the parent MTU |
ipv6 | false | enables IPv6, SLAAC observation and RDNSS |
dhcpv6 | false | adds stateful DHCPv6; requires ipv6=true |
lease_timeout | 10s | synchronous DHCP budget for Mode B |
ignore_conflicts | false | allow several networks on one bridge+VLAN |
skip_routes | false | do not copy host bridge static routes |
require_mac | false | fail endpoint creation without a Docker-supplied MAC |
Change with docker plugin set while the plugin is disabled:
| Variable | Default | Meaning |
|---|---|---|
DOCKER_NETWORK_DHCP_LOG_LEVEL | info | debug, info, warn, error |
DOCKER_NETWORK_DHCP_PROBE_TIMEOUT | 15s | Mode A DHCPv4 wait at endpoint creation (1–25s) |
DOCKER_NETWORK_DHCP_PROBE_CONCURRENCY | auto | parallel DHCP probes (NumCPU, clamped 2–16) |
DOCKER_NETWORK_DHCP_RESTORE_CONCURRENCY | auto | restore workers, same clamp |
DOCKER_NETWORK_DHCP_V6_PROBE_NEGATIVE_TTL | 10m | per-network "no DHCPv6 server" memory; 0 disables |
DOCKER_NETWORK_DHCP_RECONCILE_APIPA | enabled | false blocks new APIPA reconciliation prepares |
Opt-in synchronous allocation: docker inspect shows the DHCP address in the
IPAM block, and docker run fails fast when the server is unavailable
(no APIPA). Use the plugin as both driver and IPAM driver, with the subnet
declared:
docker network create \
--driver docker-net-dhcp:latest --ipam-driver docker-net-dhcp:latest \
--subnet 192.168.1.0/24 \
-o bridge=eth0 -o mode=macvlan -o require_mac=true \
lan-b
PLUGIN_ID=$(docker plugin inspect docker-net-dhcp --format '{{.ID}}')
curl -s --unix-socket /run/docker/plugins/${PLUGIN_ID}/net-dhcp.sock \
http://localhost/healthz | jq .
Per-endpoint lease, DHCP phase (acquiring/bound/renewing/…), IPv6
addresses with GUA/ULA classification, and remaining lease time. Prometheus
metrics on /metrics at the same socket.
docker plugin disable docker-net-dhcp
docker plugin rm docker-net-dhcp
sudo rm -rf /var/lib/docker-net-dhcp
ipv6=true and no DHCPv6 server, containers get ULA/GUA via SLAAC, but
libnetwork cannot show them in docker inspect (GlobalIPv6Address); the
authoritative view is /healthz or ip -6 addr inside the container.Content type
Image
Digest
sha256:f61814b73…
Size
12.3 MB
Last updated
about 7 hours ago
docker pull fernandodelucca/docker-net-dhcp:dev