Sign inSign up

claymore666/docker-net-dhcp

By claymore666

โ€ขUpdated 2 days ago

DHCP-leased IPs for Docker containers (bridge/macvlan/ipvlan). Same image as claymore666/net-dhcp.

Plugin
Networking
Security
Monitoring & observability
0

557

claymore666/docker-net-dhcp repository overview

โ docker-net-dhcp

Test Integration Dependencies Release OpenSSF Scorecard OpenSSF Best Practices Docs

A Docker network plugin that gives every container an address from the DHCP server your LAN already runs (your router, a Fritz!Box, dnsmasq) instead of from Docker's own IPAM, over bridge, macvlan or ipvlan, for IPv4 and IPv6. The DHCP exchange runs inside the plugin on the project's own engine, the dhcp-golibโ  library: there is no external DHCP client to install and no client process per container.

This branch is the 2.0 line and every page on it describes that build. The snippets below install the current release.

โ Requirements

  • Docker Engine. Every change is tested against the engine the integration suite runs on, 29.7.2 today, read from that run's Fixture engine drift step. It is the version this build is measured on. It is not a floor: the minimum has never been measured (#670), so the measured number is the honest one to publish.
  • Plugin interface docker.networkdriver/1.0, which is what the plugin manifest declares. The plugin negotiates the Docker API version with the daemon, so no API floor is claimed here either.
  • One directory, created once per host, before docker plugin install (the line is in the quick start below). Docker will not create a missing bind source, so without it the install fails at start-up and leaves the plugin installed but disabled, after which the identical command answers only plugin ... already exists and names nothing. Recovery: the referenceโ .
  • Architecture. linux/amd64 on the bare tag, linux/arm64 on the -arm64 tag. A Docker plugin cannot be installed from a multi-architecture manifest list, so the tag is how the architecture is chosen, in every snippet that names the image and not only the install line. Why, in full: Install, upgrade, uninstallโ .
  • Privileges. The manifest asks for host networking, the host PID namespace, the Docker socket, a bind mount of the state directory, a read-only bind mount of /var/run/docker, and CAP_NET_ADMIN, CAP_NET_RAW, CAP_SYS_ADMIN, CAP_SYS_PTRACE. docker plugin install prompts for the set; what each is for is in SECURITY.mdโ .
  • Kernel link types. Bridge mode needs veth and bridge; macvlan and ipvlan each need the kernel module of the same name. A stock distribution kernel loads one the first time that link type is asked for, so there is normally nothing to do: measured on Linux 6.12, ipvlan was absent from lsmod before the first ip link add ... type ipvlan and present after, with no modprobe. A kernel built without the type, or a host where module loading is turned off, fails docker network create for that mode.
  • Root on the host. The plugin runs as root and its socket lives under /run/docker/plugins, which only root can read. Reading /Plugin.Healthโ  therefore needs sudo. Without it curl -s prints nothing and exits 7, which is what an absent socket also gives, so a permission problem looks like a stopped plugin.
  • Mode constraints. bridge expects a host bridge you maintain; macvlan and ipvlan attach to a host NIC and change nothing on the host, at the cost of the kernel rule that a child cannot reach its own host's address. Both in macvlan / ipvlan modesโ .

โ Quick start

# Once per host, before the install. See Requirements above.
sudo mkdir -p /var/lib/net-dhcp

# amd64
docker plugin install ghcr.io/claymore666/docker-net-dhcp:v2.0.0
# arm64
docker plugin install ghcr.io/claymore666/docker-net-dhcp:v2.0.0-arm64

One network, created once. macvlan needs only a host NIC; bridge wants a bridge you bring yourself (bridge modeโ ):

docker network create -d ghcr.io/claymore666/docker-net-dhcp:v2.0.0 \
  --ipam-driver null -o mode=macvlan -o parent=eth0 lan-dhcp

docker run --rm -ti --network lan-dhcp alpine ip address show

--ipam-driver null is mandatory: it stops Docker handing out addresses that would collide with the real LAN. On arm64 the -arm64 tag goes in this line too, because a network records the tagged reference as its driver. Add -o ipv6=true for a DHCPv6 lease beside the v4 one.

After that, plain Compose. No static addresses, no sidecar, nothing per container:

services:
  app:
    image: nginx
    networks: [lan-dhcp]

networks:
  lan-dhcp:
    external: true

โ Why this one

  • The address comes from the LAN's own server, so the router's lease table, its MAC reservations and, with -o register_dns=true, its DNS all see the container as one more host on the network. The alternative is a hand-assigned address in every Compose file.
  • The lease is held for as long as the container runs. Renewal, rebind, NAK and expiry run in the plugin, one client per endpoint, and the lifecycle is visible on the health endpointโ . There is no external DHCP client to install, supervise or reap.
  • IPv6 is the same one line. -o ipv6=true adds a DHCPv6 lease with its own timers, its own counters and a DUID that survives a restart.
  • A restart keeps the address. In bridge and macvlan the MAC is carried across docker restart, so a server-side reservation still matches and the old address is re-requested; a plugin restart or upgrade re-adopts running containers, so their leases do not lapse (howโ ).
  • No host plumbing per container. macvlan and ipvlan attach to a NIC that is already there: no bridge to build, no route to add, nothing on the host to undo afterwards.

What is planned, and what this project has decided not to do, is on the roadmapโ .

โ Origin and licence

This began as a fork of devplayer0/docker-net-dhcpโ  (quiet since 2021); since 2.0 it is its own product, with its own DHCP engine.

GPL-3.0. See LICENSE.mdโ . The upstream project is GPL-3.0 and this derivative stays under the same licence.

โ Documentation

Published at https://claymore666.github.io/docker-net-dhcp/โ , one version per release; the same pages live in docs/โ .

Images go to GHCR (ghcr.io/claymore666/docker-net-dhcp:vX.Y.Z, primary) and are mirrored to Docker Hub (claymore666/net-dhcp:vX.Y.Z).

โ Verifying releases

Every release from v1.1.0 is cosign-signed (keyless) on both registries and ships an SBOM; SLSA build provenance is attested for the GHCR image only, so verify provenance against the ghcr.io reference. Both commands need cosign v3 or newer. v2 cannot read the bundle format the release signs with, and it fails in a way that looks like a broken signature. Replace VERSION:

cosign verify ghcr.io/claymore666/docker-net-dhcp:VERSION \
  --certificate-identity-regexp '^https://github.com/claymore666/docker-net-dhcp/.github/workflows/release.yml@' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com

gh attestation verify oci://ghcr.io/claymore666/docker-net-dhcp:VERSION --repo claymore666/docker-net-dhcp

The whole procedure, including rebuilding the binaries yourself, is in Verifying releasesโ .

โ Project & community

โ Contributing

Contributions are welcome. Open a pull request against the dev branch; Contributingโ  is the whole of what is asked, and make check runs the fast CI lane locally in about a minute. In short:

  • Go code is gofmt-formatted and passes go vet and staticcheckโ ; shell and workflow files pass shellcheck and actionlint.
  • New functionality is expected to ship with tests, and a per-package coverage ratchet enforces that at release time.
  • Commits and pull request descriptions carry no AI-assistant attribution and the commit author is a person. The attribution check reads every commit and the description.
  • Every required check must be green; branch protection holds the list.
  • Looking for somewhere to start? There are no starter tasks open at the moment. The ones that were seeded were closed as the work they described landed, and this section says so instead of sending you to an empty list. If you would like a first task, ask in Discussionsโ  and say what interests you: a subsystem, a bug you hit, a piece of the documentation you found thin. One will be scoped against it. When starter tasks exist again they carry the good first issue label and this section links to them.

This is solo-maintained, so please allow a few days for a response.

Tag summary

Content type

Plugin

Digest

sha256:d8c0c8a80โ€ฆ

Size

13.3 MB

Last updated

2 days ago

docker plugin install claymore666/docker-net-dhcp