Skip to content

maxfield-allison/dnsweaver

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

382 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

dnsweaver

Release Docker Pulls License Go Version

Automatic DNS record management for Docker, Kubernetes, and Proxmox VE workloads with multi-provider support.

dnsweaver watches Docker events, Kubernetes resources, and Proxmox VE clusters to automatically create and delete DNS records. Unlike single-provider tools, dnsweaver supports split-horizon DNS, multiple DNS providers simultaneously, and works across Docker, Kubernetes, and Proxmox platforms.

πŸ“š Full Documentation

Features

  • πŸ”€ Multi-Provider Support β€” Route different domains to different DNS providers
  • 🌐 Split-Horizon DNS β€” Internal and external records from the same container labels
  • 🐳 Docker & Swarm β€” Works with standalone Docker and Docker Swarm clusters
  • ☸️ Kubernetes Native β€” Watches Ingress, IngressRoute, HTTPRoute, and Service resources via Helm or Kustomize
  • πŸ–₯️ Proxmox VE β€” Auto-creates A records for VMs (via QEMU guest agent) and LXC containers
  • πŸ—οΈ 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
  • πŸ›‘οΈ Hardened TLS β€” Unified per-instance TLS controls (custom CA, mTLS client certs, SNI override, configurable min version; TLS 1.2 floor by default) for every HTTP-based provider and the Proxmox source
  • 🏷️ Traefik Integration β€” Parses traefik.http.routers.*.rule labels to extract hostnames
  • πŸš€ Caddy Integration β€” Parses caddy / caddy_<n> labels from caddy-docker-proxy
  • πŸ”§ nginx-proxy Integration β€” Parses VIRTUAL_HOST labels used by jwilder/nginx-proxy
  • πŸ“Š Observable β€” Prometheus metrics, health endpoints, structured logging
  • πŸ”‘ Secrets Support β€” Docker secrets and Kubernetes Secrets via _FILE suffix variables

Supported Providers

Provider Record Types Notes
Technitium A, AAAA, CNAME, SRV, TXT Full-featured self-hosted DNS
Cloudflare A, AAAA, CNAME, SRV, TXT With optional proxy support
RFC 2136 A, AAAA, CNAME, SRV, TXT BIND, Windows DNS, PowerDNS, Knot
Pi-hole A, CNAME API or file mode
AdGuard Home A, AAAA, CNAME DNS rewrite management
dnsmasq A, CNAME File-based configuration
Webhook Any Custom integrations

Quick Start

Installation

# Docker Hub
docker pull maxamill/dnsweaver:latest

# GitHub Container Registry
docker pull ghcr.io/maxfield-allison/dnsweaver:latest

Basic Example

services:
  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=192.0.2.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: true

How It Works

flowchart LR
    A["Docker / Swarm"] --> B["dnsweaver"]
    D["Kubernetes"] --> B
    P["Proxmox VE"] --> B
    B --> C["DNS Providers<br/>(create / update / delete)"]
Loading
  1. A container starts with a Traefik label (or a Kubernetes Ingress/HTTPRoute is created):

    labels:
      - "traefik.http.routers.myapp.rule=Host(`myapp.home.example.com`)"
  2. dnsweaver extracts the hostname and matches it against configured provider domain patterns

  3. The matching provider creates the DNS record:

    • A record: myapp.home.example.com β†’ 192.0.2.100
    • CNAME: myapp.example.com β†’ proxy.example.com
  4. When the container stops (or the Kubernetes resource is deleted), the DNS record is automatically cleaned up

Documentation

Topic Description
Getting Started Installation and first configuration
Configuration Environment variables reference
Providers Provider-specific setup guides
Sources Docker, Kubernetes, Proxmox, Traefik file sources
Kubernetes Kubernetes deployment with Helm/Kustomize
Proxmox VE Auto-DNS for VMs and LXC containers
Split-Horizon DNS Internal + external records
Docker Swarm Swarm deployment guide
Observability Metrics, logging, and health checks
FAQ Common questions and troubleshooting

TLS Configuration

Every HTTP-based provider (Technitium, AdGuard Home, Cloudflare, Pi-hole, Webhook) and the Proxmox source share a single TLS configuration surface:

Env key (per instance) Purpose
DNSWEAVER_<NAME>_TLS_CA_FILE Trust a private CA bundle (PEM)
DNSWEAVER_<NAME>_TLS_CERT_FILE / _TLS_KEY_FILE Present a client certificate (mTLS)
DNSWEAVER_<NAME>_TLS_SERVER_NAME Override SNI / hostname verification
DNSWEAVER_<NAME>_TLS_SKIP_VERIFY Disable verification (development only)
DNSWEAVER_<NAME>_TLS_MIN_VERSION 1.2 (default) or 1.3

The Proxmox source uses the same keys under DNSWEAVER_PROXMOX_TLS_*. The legacy *_INSECURE_SKIP_VERIFY and DNSWEAVER_PROXMOX_VERIFY_TLS variables are still accepted but emit a deprecation warning at startup β€” migrate to the unified TLS_SKIP_VERIFY keys. See the Environment Reference and SECURITY.md for full details and recipes.

Kubernetes Quick Start

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-namespace

dnsweaver 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: "192.0.2.100"
spec:
  rules:
    - host: app.example.com

See the Kubernetes deployment guide for full configuration.

Split-Horizon DNS Example

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=192.0.2.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.com

With this configuration, when app.example.com starts:

  • Internal DNS β†’ A record β†’ 192.0.2.100
  • External DNS β†’ CNAME record β†’ tunnel.example.com

Contributing

Contributions are welcome! See CONTRIBUTING for guidelines.

License

MIT License