- Go 98.9%
- Dockerfile 1.1%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
|
||
| .forgejo/workflows | ||
| .dockerignore | ||
| .env.example | ||
| .gitignore | ||
| compose.yaml | ||
| Dockerfile | ||
| go.mod | ||
| go.sum | ||
| main.go | ||
| main_test.go | ||
| README.md | ||
moby-dns
moby-dns keeps authoritative DNS synchronized with containers running on a
Docker/Moby network. It discovers containers through the Docker Engine API and
sends TSIG-signed RFC 2136 updates directly to an existing DNS server.
It manages:
- one IPv4
Arecord per running container; - the matching reverse
PTRrecord; - IP-address changes; and
- safe cleanup when a managed container stops, is removed, or leaves the monitored network.
It does not run a DNS server and does not create CNAME records.
Container image
Forgejo Actions builds AMD64 and ARM64 images from main:
forgejo.ofkm.us/ofkm/moby-dns:latest
Configuration
Copy .env.example to .env and set these values:
| Variable | Required | Description |
|---|---|---|
DNS_SERVER |
yes | RFC 2136 server address |
DNS_PORT |
no | DNS update and query port; defaults to 53 |
DNS_ZONE |
yes | Forward zone, as a fully qualified name |
DNS_REVERSE_ZONE |
yes | IPv4 reverse zone, as a fully qualified name |
TSIG_KEY_NAME |
yes | TSIG key name |
TSIG_SECRET |
yes | Base64-encoded TSIG secret |
DOCKER_NETWORK |
no | Docker network to inspect; defaults to vlan25 |
RECORD_TTL |
no | Managed record TTL; defaults to 60 |
SYNC_INTERVAL |
no | Reconciliation interval; defaults to 30s |
Only running containers attached to DOCKER_NETWORK are considered. Container
names are lowercased, underscores and other invalid characters become hyphens,
and the forward zone is appended.
For example, immich_server becomes
immich-server.containers.example.com..
Labels
Override a container's record name:
labels:
- "moby-dns.hostname=custom-name"
Exclude a container:
labels:
- "moby-dns.ignore=true"
The label keys can be changed with HOSTNAME_LABEL and IGNORE_LABEL.
Run with Compose
The included OFKM deployment uses an existing Docker network and an external state volume. Compose does not create either resource.
docker volume create moby-dns-state
cp .env.example .env
chmod 600 .env
# Edit .env, and adjust vlan25/IP settings in compose.yaml when needed.
docker compose up -d
The state volume records which values moby-dns owns. On cleanup, it removes
only the previously owned A address and PTR target rather than deleting an
unrelated record set.
BIND example
Both zones must allow updates from the configured key:
key "moby-dns." {
algorithm hmac-sha256;
secret "base64-secret-here";
};
zone "containers.example.com" {
type primary;
file "pri/containers.example.com.zone";
allow-update { key "moby-dns."; };
};
zone "2.0.192.in-addr.arpa" {
type primary;
file "pri/2.0.192.in-addr.arpa.zone";
allow-update { key "moby-dns."; };
};
Security
The updater only issues read requests to the Docker API, but access to the Docker socket is inherently privileged even when the socket is mounted read-only. Run the image only on a trusted host and protect the TSIG secret.
The runtime image is scratch, read-only, has all Linux capabilities dropped,
and persists only /data/state.json.
Development
go test ./...
go vet ./...
docker build -t moby-dns:local .