Sign inSign up

cplieger/docker-radvd

By cplieger

•Updated 6 days ago

Minimal Alpine image for radvd (IPv6 Router Advertisement Daemon) with HA-aware entrypoint

Image
Networking
1

8.0K

cplieger/docker-radvd repository overview

⁠docker-radvd

Run radvd⁠ (the Linux IPv6 Router Advertisement Daemon) in a container. Bring your own radvd.conf.

⁠What it does

radvd⁠ emits IPv6 Router Advertisements (RAs) onto the LAN so hosts can do SLAAC (StateLess Address AutoConfiguration): learn the local prefix(es), default router, and DNS. Without an RA emitter on the LAN, IPv6 hosts stay link-local-only and can't route off-segment.

This image is a minimal Alpine wrapper around upstream radvd, compiled from the pinned release tarball, plus a small POSIX entrypoint that:

  • Checks the mounted radvd.conf node: the entrypoint refuses a path that is not a regular file at startup or reload. It warns when its bounded node read fails, then leaves the config settings to radvd. A config radvd rejects outright, such as one defining no interface block, is left to radvd: radvd logs its own error and exits, and the entrypoint reports that exit.
  • Drops privileges: radvd opens its raw socket as root, then runs its worker as the unprivileged radvd user (--username=radvd); a small root privsep helper stays beside it, so ps inside the container shows one radvd-owned process and one root-owned one
  • Supervises radvd: turns SIGHUP into a config reload, refusing the reload and keeping the running daemon when the config would not start; forwards SIGTERM for graceful shutdown. A stop that arrives before radvd has started wins immediately and exits 0 without starting it. An unexpected radvd exit propagates to Docker's restart policy. See Reloading⁠ for the docker kill caveat.
  • Logs to stderr with structured key=value lines, captured by docker logs
⁠Why this design
  • Generic upstream-only: no env-var-to-config translation, no bundled prefixes; you supply your own radvd.conf. The one env var, RADVD_DEBUG_LEVEL, tunes radvd's log verbosity only (see Configuration reference⁠)
  • Bind-mount only: single read-only :ro mount of /etc/radvd
  • Healthcheck: pidof radvd (CMD form, no shell needed)
  • Multi-arch: linux/amd64 and linux/arm64

⁠Pull

docker pull cplieger/docker-radvd:latest

Also published to ghcr.io/cplieger/docker-radvd with identical images and tags. Release versions are tagged vX.Y.Z alongside latest.

⁠Quick start

# Example compose for docker-radvd. See the README for all configuration options and hardening.
services:
  radvd:
    image: ghcr.io/cplieger/docker-radvd:latest
    container_name: radvd
    restart: unless-stopped

    # RAs are ICMPv6 on a real LAN interface, so radvd needs host networking (or a macvlan).
    # Advertising a default route also needs the host's net.ipv6.conf.all.forwarding at
    # 1 or 2, which compose cannot set; AdvDefaultLifetime 0 does not. See the README.
    network_mode: host
    cap_add:
      - NET_RAW  # required: raw ICMPv6 socket to emit RAs

    volumes:
      - "./radvd:/etc/radvd:ro"  # provide your radvd.conf here

⁠Documentation

⁠License

Apache-2.0. See LICENSE⁠.

The image carries the license text of every bundled component under /usr/share/licenses/. The Alpine packages in the image ship no license file upstream, so their license texts are kept under licenses/ in this repository and copied in.

It packages upstream radvd⁠, which carries its own BSD-style permissive license: the COPYRIGHT file from the release tarball, shipped at /usr/share/licenses/radvd/COPYRIGHT. The daemon is compiled from the release asset https://github.com/radvd-project/radvd/releases/download/<version>/radvd-<version>.tar.gz, at the version the RADVD_VERSION build argument pins and verified against the RADVD_SHA256 pin before extraction. The build applies no patches, so this repository's Dockerfile⁠ and that tarball are the complete recipe for the binary in the image.

Tag summary

Content type

Image

Digest

sha256:87c04572a…

Size

3.8 MB

Last updated

6 days ago

docker pull cplieger/docker-radvd