Automatic DNS record management for Docker and Kubernetes workloads with multi-provider support.
dnsweaver watches Docker events and Kubernetes resources to automatically create and delete DNS records. Unlike single-provider tools, dnsweaver supports split-horizon DNS, multiple DNS providers simultaneously, and works across both Docker and Kubernetes platforms.
- 🔀 Multi-Provider Support — Route different domains to different DNS providers
- 🌐 Split-Horizon DNS — Internal and external records from the same container labels
- 🐳 Docker & Swarm Native — Works with standalone Docker and Docker Swarm clusters
- ☸️ Kubernetes Support — Watches Ingress, IngressRoute, HTTPRoute, and Service resources
- 🏗️ Multi-Instance Safe — Run multiple dnsweaver instances on the same DNS zone without conflicts
- 🔒 Socket Proxy Compatible — Connect via TCP to a Docker socket proxy for improved security
- 🏷️ Traefik Integration — Parses
traefik.http.routers.*.rulelabels to extract hostnames - 📊 Observable — Prometheus metrics, health endpoints, structured logging
- 🔑 Secrets Support — Docker secrets and Kubernetes Secrets via
_FILEsuffix variables
| Provider | Record Types | Notes |
|---|---|---|
| Technitium | A, AAAA, CNAME, SRV, TXT | Full-featured self-hosted DNS |
| Cloudflare | A, AAAA, CNAME, TXT | With optional proxy support |
| RFC 2136 | A, AAAA, CNAME, SRV, TXT | BIND, Windows DNS, PowerDNS, Knot |
| Pi-hole | A, AAAA, CNAME | API or file mode |
| dnsmasq | A, AAAA, CNAME | File-based configuration |
| Webhook | Any | Custom integrations |
# Docker Hub
docker pull maxamill/dnsweaver:latest
# GitHub Container Registry
docker pull ghcr.io/maxfield-allison/dnsweaver:latestservices:
dnsweaver:
image: maxamill/dnsweaver:latest
restart: unless-stopped
environment:
- DNSWEAVER_INSTANCES=internal-dns
- DNSWEAVER_INTERNAL_DNS_TYPE=technitium
- DNSWEAVER_INTERNAL_DNS_URL=http://dns.internal:5380
- DNSWEAVER_INTERNAL_DNS_TOKEN_FILE=/run/secrets/technitium_token
- DNSWEAVER_INTERNAL_DNS_ZONE=home.example.com
- DNSWEAVER_INTERNAL_DNS_RECORD_TYPE=A
- DNSWEAVER_INTERNAL_DNS_TARGET=10.0.0.100
- DNSWEAVER_INTERNAL_DNS_DOMAINS=*.home.example.com
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
secrets:
- technitium_token
secrets:
technitium_token:
external: trueflowchart LR
A["Docker Events<br/>(start/stop)"] --> B["dnsweaver<br/>(matching)"]
B --> C["DNS Providers<br/>(A/CNAME/SRV)"]
-
A container starts with a Traefik label:
labels: - "traefik.http.routers.myapp.rule=Host(`myapp.home.example.com`)"
-
dnsweaver extracts the hostname and matches it against configured provider domain patterns
-
The matching provider creates the DNS record:
- A record:
myapp.home.example.com → 10.0.0.100 - CNAME:
myapp.example.com → proxy.example.com
- A record:
-
When the container stops, the DNS record is automatically cleaned up
| Topic | Description |
|---|---|
| Getting Started | Installation and first configuration |
| Configuration | Environment variables reference |
| Providers | Provider-specific setup guides |
| Kubernetes | Kubernetes deployment with Helm/Kustomize |
| Split-Horizon DNS | Internal + external records |
| Docker Swarm | Swarm deployment guide |
| Observability | Metrics, logging, and health checks |
| FAQ | Common questions and troubleshooting |
Deploy dnsweaver to watch Kubernetes resources for DNS management:
# Using Kustomize
kubectl apply -k https://github.com/maxfield-allison/dnsweaver/deploy/kustomize/base
# Using Helm
helm install dnsweaver deploy/helm/dnsweaver/ \
--namespace dnsweaver --create-namespacednsweaver automatically detects hostnames from Ingress, IngressRoute (Traefik), HTTPRoute (Gateway API), and Service resources. Use dnsweaver.dev/* annotations for per-resource overrides:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app
annotations:
dnsweaver.dev/record-type: "A"
dnsweaver.dev/target: "10.0.0.100"
spec:
rules:
- host: app.example.comSee the Kubernetes deployment guide for full configuration.
Manage internal and external DNS from the same container labels:
environment:
- DNSWEAVER_INSTANCES=internal,external
# Internal: Technitium → private IP
- DNSWEAVER_INTERNAL_TYPE=technitium
- DNSWEAVER_INTERNAL_RECORD_TYPE=A
- DNSWEAVER_INTERNAL_TARGET=10.0.0.100
- DNSWEAVER_INTERNAL_DOMAINS=*.example.com
# External: Cloudflare → tunnel CNAME
- DNSWEAVER_EXTERNAL_TYPE=cloudflare
- DNSWEAVER_EXTERNAL_RECORD_TYPE=CNAME
- DNSWEAVER_EXTERNAL_TARGET=tunnel.example.com
- DNSWEAVER_EXTERNAL_DOMAINS=*.example.comWith this configuration, when app.example.com starts:
- Internal DNS →
Arecord →10.0.0.100 - External DNS →
CNAMErecord →tunnel.example.com
Contributions are welcome! See CONTRIBUTING for guidelines.