Automatically manages DNS records based on Traefik routing, Docker events and labels.
10K+
A service that automatically manages DNS records based on Traefik routing configuration.
| Provider | Status | Implementation Details |
|---|---|---|
| Full support for all record types and features | ||
| Full support for all record types and features | ||
| Coming soon |
version: '3'
services:
traefik-dns-manager:
image: eafxx/traefik-dns-manager:latest
container_name: traefik-dns-manager
restart: unless-stopped
user: "0:0" # Required for Docker socket access
environment:
# DNS Provider (choose one)
- DNS_PROVIDER=cloudflare # Options: cloudflare, digitalocean
# Cloudflare settings (if using Cloudflare)
- CLOUDFLARE_TOKEN=your_cloudflare_api_token
- CLOUDFLARE_ZONE=example.com
# DigitalOcean settings (if using DigitalOcean)
- DO_TOKEN=your_digitalocean_api_token
- DO_DOMAIN=example.com
# Traefik API settings
- TRAEFIK_API_URL=http://traefik:8080/api
- LOG_LEVEL=INFO
# DNS record management
- CLEANUP_ORPHANED=true # Set to true to automatically remove DNS records when containers are removed
- PRESERVED_HOSTNAMES=static.example.com,api.example.com,*.admin.example.com # Hostnames to preserve (even when orphaned)
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./dns-records.json:/app/dns-records.json # Persist tracking information
networks:
- traefik-network
Cloudflare requires an API token with DNS edit permissions for your zone:
environment:
- DNS_PROVIDER=cloudflare
- CLOUDFLARE_TOKEN=your_cloudflare_api_token
- CLOUDFLARE_ZONE=example.com
Cloudflare-specific features:
dns.proxied or dns.cloudflare.proxied labelsDigitalOcean requires an API token with write access to your domain:
environment:
- DNS_PROVIDER=digitalocean
- DO_TOKEN=your_digitalocean_api_token
- DO_DOMAIN=example.com
DigitalOcean-specific notes:
proxied labels are ignored)The DNS Manager supports the following labels for customising DNS record creation:
| Label | Description | Default |
|---|---|---|
dns.skip | Skip DNS management for this service | false |
dns.manage | Enable DNS management for this service | Depends on DNS_DEFAULT_MANAGE |
dns.type | DNS record type (A, AAAA, CNAME, etc.) | CNAME or A for apex domains |
dns.content | Record content/value | Domain for CNAME, Public IP for A |
dns.ttl | Record TTL in seconds | 1 (Auto) for Cloudflare, 30 for DigitalOcean |
| Label | Description | Default | Supported Providers |
|---|---|---|---|
dns.cloudflare.skip | Skip Cloudflare DNS management for this service | false | Cloudflare |
dns.cloudflare.manage | Enable Cloudflare DNS management for this service | Depends on DNS_DEFAULT_MANAGE | Cloudflare |
dns.cloudflare.type | DNS record type for Cloudflare | CNAME or A for apex domains | Cloudflare |
dns.cloudflare.content | Record content for Cloudflare | Domain for CNAME, Public IP for A | Cloudflare |
dns.cloudflare.proxied | Enable Cloudflare proxy (orange cloud) | true | Cloudflare |
dns.cloudflare.ttl | Record TTL for Cloudflare in seconds | 1 (Auto) | Cloudflare |
dns.digitalocean.skip | Skip DigitalOcean DNS management for this service | false | DigitalOcean |
dns.digitalocean.manage | Enable DigitalOcean DNS management for this service | Depends on DNS_DEFAULT_MANAGE | DigitalOcean |
dns.digitalocean.type | DNS record type for DigitalOcean | CNAME or A for apex domains | DigitalOcean |
dns.digitalocean.content | Record content for DigitalOcean | Domain for CNAME, Public IP for A | DigitalOcean |
dns.digitalocean.ttl | Record TTL for DigitalOcean in seconds | 30 (Minimum) | DigitalOcean |
| Label | Applicable Types | Description |
|---|---|---|
dns.priority or dns.<provider>.priority | MX, SRV | Priority value |
dns.weight or dns.<provider>.weight | SRV | Weight value |
dns.port or dns.<provider>.port | SRV | Port value |
dns.flags or dns.<provider>.flags | CAA | Flags value |
dns.tag or dns.<provider>.tag | CAA | Tag value |
The system uses the following precedence order when reading labels:
dns.cloudflare.type)dns.type)This allows you to set global defaults, override them with generic DNS settings, and further override with provider-specific settings when needed.
Different DNS providers have different requirements for TTL values:
| Provider | Minimum TTL | Default TTL | Notes |
|---|---|---|---|
| Cloudflare | 1 second | 1 second (Auto) | TTL is ignored for proxied records (always Auto) |
| DigitalOcean | 30 seconds | 30 seconds | Values below 30 are automatically adjusted to 30 |
Just use standard Traefik labels, and DNS records are automatically created:
services:
my-app:
image: my-image
labels:
- "traefik.enable=true"
- "traefik.http.routers.my-app.rule=Host(`app.example.com`)"
- "traefik.http.routers.my-app.entrypoints=https"
This will create a CNAME record for app.example.com pointing to your domain.
services:
my-service:
image: my-image
labels:
- "traefik.enable=true"
- "traefik.http.routers.my-service.rule=Host(`service.example.com`)"
- "dns.proxied=false" # Use generic label
# OR "dns.cloudflare.proxied=false" # Use provider-specific label
services:
my-app:
image: my-image
labels:
- "traefik.enable=true"
- "traefik.http.routers.my-app.rule=Host(`app.example.com`)"
- "dns.type=A"
- "dns.content=203.0.113.10" # Custom IP address
services:
my-app:
image: my-image
labels:
- "traefik.enable=true"
- "traefik.http.routers.my-app.rule=Host(`app.example.com`)"
- "dns.digitalocean.ttl=3600" # Set TTL to 1 hour (3600 seconds)
services:
internal-app:
image: internal-image
labels:
- "traefik.enable=true"
- "traefik.http.routers.internal.rule=Host(`internal.example.com`)"
- "dns.skip=true" # Skip DNS management for all providers
# OR "dns.cloudflare.skip=true" # Skip just Cloudflare DNS management
services:
public-app:
image: public-image
labels:
- "traefik.enable=true"
- "traefik.http.routers.public.rule=Host(`public.example.com`)"
- "dns.manage=true" # Explicitly enable DNS management for all providers
# OR "dns.cloudflare.manage=true" # Enable just for Cloudflare
services:
mail-service:
image: mail-image
labels:
- "traefik.enable=true"
- "traefik.http.routers.mail.rule=Host(`example.com`)"
- "dns.type=MX"
- "dns.content=mail.example.com"
- "dns.priority=10"
| Variable | Description | Default | Required |
|---|---|---|---|
DNS_PROVIDER | DNS provider to use | cloudflare | No |
| Variable | Description | Default | Required if using Cloudflare |
|---|---|---|---|
CLOUDFLARE_TOKEN | Cloudflare API token with DNS edit permissions | - | Yes |
CLOUDFLARE_ZONE | Your domain name (e.g., example.com) | - | Yes |
| Variable | Description | Default | Required if using DigitalOcean |
|---|---|---|---|
DO_TOKEN | DigitalOcean API token with write access | - | Yes |
DO_DOMAIN | Your domain name (e.g., example.com) | - | Yes |
| Variable | Description | Default | Required |
|---|---|---|---|
TRAEFIK_API_URL | URL to Traefik API | http://traefik:8080/api | No |
TRAEFIK_API_USERNAME | Username for Traefik API basic auth | - | No |
TRAEFIK_API_PASSWORD | Password for Traefik API basic auth | - | No |
| Variable | Description | Default | Required |
|---|---|---|---|
DNS_LABEL_PREFIX | Base prefix for DNS labels | dns. | No |
DNS_DEFAULT_TYPE | Default DNS record type | CNAME | No |
DNS_DEFAULT_CONTENT | Default record content | Value of CLOUDFLARE_ZONE or DO_DOMAIN | No |
DNS_DEFAULT_PROXIED | Default Cloudflare proxy status | true | No |
DNS_DEFAULT_TTL | Default TTL in seconds | 1 (Auto for Cloudflare) or minimum TTL for provider | No |
DNS_DEFAULT_MANAGE | Global DNS management mode | true | No |
| Variable | Description | Default | Required |
|---|---|---|---|
PUBLIC_IP | Manual override for public IPv4 | Auto-detected | No |
PUBLIC_IPV6 | Manual override for public IPv6 | Auto-detected | No |
IP_REFRESH_INTERVAL | How often to refresh IP (ms) | 3600000 (1 hour) | No |
| Variable | Description | Default | Required |
|---|---|---|---|
POLL_INTERVAL | How often to poll Traefik API (ms) | 60000 (1 min) | No |
WATCH_DOCKER_EVENTS | Whether to watch Docker events | true | No |
CLEANUP_ORPHANED | Whether to remove orphaned DNS records | false | No |
PRESERVED_HOSTNAMES | Comma-separated list of hostnames to exclude from cleanup | - | No |
DOCKER_SOCKET | Path to Docker socket | /var/run/docker.sock | No |
LOG_LEVEL | Logging verbosity (ERROR, WARN, INFO, DEBUG, TRACE) | INFO | No |
DNS_CACHE_REFRESH_INTERVAL | How often to refresh DNS cache (ms) | 3600000 (1 hour) | No |
When containers are removed, their DNS records can be automatically cleaned up by enabling the CLEANUP_ORPHANED setting:
environment:
- CLEANUP_ORPHANED=true
This will:
To avoid premature deletion, the system will:
You can specify hostnames that should never be deleted, even if they become orphaned:
environment:
- PRESERVED_HOSTNAMES=static.example.com,api.example.com,*.admin.example.com
This supports:
api.example.com)*.admin.example.com) which will preserve all subdomains that match the patternPreserved hostnames will be logged during startup and skipped during any cleanup operations.
The application maintains a persistent record of all DNS entries it creates in a JSON file dns-records.json. This enables:
For optimal reliability, mount this file as a volume in your Docker setup:
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./dns-records.json:/app/dns-records.json
TraeDnsManager supports two operational modes for DNS management:
DNS_DEFAULT_MANAGE=true or leave it unsetdns.skip=true or dns.<provider>.skip=true labelDNS_DEFAULT_MANAGE=falsedns.manage=true or dns.<provider>.manage=true labelThe application includes a configurable logging system to help with monitoring and troubleshooting:
ERROR - Only critical errors that break functionalityWARN - Important warnings that don't break functionalityINFO - Key operational information (default)DEBUG - Detailed information for troubleshootingTRACE - Extremely detailed information for deep troubleshootingThe default level is INFO, which provides a clean, readable output with important operational information. Set the LOG_LEVEL environment variable to change the logging verbosity.
✅ Starting TráfegoDNS
ℹ️ Cloudflare Zone: example.com
ℹ️ Processing 30 hostnames for DNS management
✅ Created A record for example.com
ℹ️ 29 DNS records are up to date
✅ TráfegoDNS running successfully
The application includes built-in performance optimisations to reduce API calls and improve efficiency:
DNS records from providers are cached in memory to reduce API calls:
DNS_CACHE_REFRESH_INTERVAL variableDNS record updates are processed in batches:
This significantly reduces API calls to DNS providers, especially for deployments with many hostnames.
The DNS Manager automatically detects apex domains (e.g., example.com) and uses A records with your public IP instead of CNAME records, which are not allowed at the apex domain level.
# Clone the repository
git clone https://github.com/elmerfds/traefik-dns-manager.git
cd traefik-dns-manager
# Build the Docker image
docker build -t traefik-dns-manager .
# Run the container
docker run -d \
--name traefik-dns-manager \
--user 0:0 \
-e CLOUDFLARE_TOKEN=your_token \
-e CLOUDFLARE_ZONE=example.com \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
traefik-dns-manager
MIT
Content type
Image
Digest
sha256:619abc751…
Size
70.3 MB
Last updated
5 months ago
docker pull eafxx/trafegodns:pr-363-v2-20260208