eafxx/trafegodns

By eafxx

Updated 5 months ago

Automatically manages DNS records based on Traefik routing, Docker events and labels.

Image
Networking
Web servers
1

10K+

eafxx/trafegodns repository overview

TráfegoDNS

TráfegoDNS Logo

A service that automatically manages DNS records based on Traefik routing configuration.

Features

  • 🔄 Automatic DNS record management based on Traefik Host rules
  • 👀 Real-time monitoring of Docker container events
  • 🏷️ Support for multiple DNS record types (A, AAAA, CNAME, MX, TXT, SRV, CAA)
  • 🌐 Automatic public IP detection for apex domains
  • 🎛️ Fine-grained control with service-specific labels
  • 💪 Fault-tolerant design with retry mechanisms
  • 🧹 Optional cleanup of orphaned DNS records with preservation capabilities
  • 📊 Optimised performance with DNS caching and batch processing
  • 🖨️ Configurable logging levels for better troubleshooting
  • 🔌 Multi-provider support with provider-agnostic label system
  • 🔒 Preserves manually created DNS records using smart tracking system
  • 🛡️ Support for explicitly preserving specific hostnames from cleanup

Supported DNS Providers

ProviderStatusImplementation Details
CloudflareStableFull support for all record types and features
DigitalOceanStableFull support for all record types and features
AWSPlannedComing soon

Quick Start

Docker Compose
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

DNS Provider Configuration

Cloudflare

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:

  • Proxying (orange cloud) through dns.proxied or dns.cloudflare.proxied labels
  • Ultra-low TTL support (as low as 1 second)
  • Automatic handling of apex domains
DigitalOcean

DigitalOcean 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:

  • Minimum TTL of 30 seconds (enforced by provider)
  • No proxying support (all proxied labels are ignored)
  • Automatically adds trailing dots for domain names as required by DigitalOcean

Service Labels

The DNS Manager supports the following labels for customising DNS record creation:

Basic Labels (Provider-Agnostic)
LabelDescriptionDefault
dns.skipSkip DNS management for this servicefalse
dns.manageEnable DNS management for this serviceDepends on DNS_DEFAULT_MANAGE
dns.typeDNS record type (A, AAAA, CNAME, etc.)CNAME or A for apex domains
dns.contentRecord content/valueDomain for CNAME, Public IP for A
dns.ttlRecord TTL in seconds1 (Auto) for Cloudflare, 30 for DigitalOcean
Provider-Specific Labels (Override Provider-Agnostic Labels)
LabelDescriptionDefaultSupported Providers
dns.cloudflare.skipSkip Cloudflare DNS management for this servicefalseCloudflare
dns.cloudflare.manageEnable Cloudflare DNS management for this serviceDepends on DNS_DEFAULT_MANAGECloudflare
dns.cloudflare.typeDNS record type for CloudflareCNAME or A for apex domainsCloudflare
dns.cloudflare.contentRecord content for CloudflareDomain for CNAME, Public IP for ACloudflare
dns.cloudflare.proxiedEnable Cloudflare proxy (orange cloud)trueCloudflare
dns.cloudflare.ttlRecord TTL for Cloudflare in seconds1 (Auto)Cloudflare
dns.digitalocean.skipSkip DigitalOcean DNS management for this servicefalseDigitalOcean
dns.digitalocean.manageEnable DigitalOcean DNS management for this serviceDepends on DNS_DEFAULT_MANAGEDigitalOcean
dns.digitalocean.typeDNS record type for DigitalOceanCNAME or A for apex domainsDigitalOcean
dns.digitalocean.contentRecord content for DigitalOceanDomain for CNAME, Public IP for ADigitalOcean
dns.digitalocean.ttlRecord TTL for DigitalOcean in seconds30 (Minimum)DigitalOcean
Type-Specific Labels
LabelApplicable TypesDescription
dns.priority or dns.<provider>.priorityMX, SRVPriority value
dns.weight or dns.<provider>.weightSRVWeight value
dns.port or dns.<provider>.portSRVPort value
dns.flags or dns.<provider>.flagsCAAFlags value
dns.tag or dns.<provider>.tagCAATag value

Label Precedence

The system uses the following precedence order when reading labels:

  1. Provider-specific labels (e.g., dns.cloudflare.type)
  2. Generic DNS labels (e.g., dns.type)
  3. Default values from configuration

This allows you to set global defaults, override them with generic DNS settings, and further override with provider-specific settings when needed.

Provider-Specific TTL Requirements

Different DNS providers have different requirements for TTL values:

ProviderMinimum TTLDefault TTLNotes
Cloudflare1 second1 second (Auto)TTL is ignored for proxied records (always Auto)
DigitalOcean30 seconds30 secondsValues below 30 are automatically adjusted to 30

Usage Examples

Basic Service with Default Settings

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.

Disable Cloudflare Proxy for Media Servers
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
Use A Record with Custom IP
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
Set Custom TTL for DigitalOcean DNS
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)
Skip DNS Management for a Service
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
Opt-in DNS Management (when DNS_DEFAULT_MANAGE=false)
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
Create MX Record
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"

Environment Variables

DNS Provider Selection
VariableDescriptionDefaultRequired
DNS_PROVIDERDNS provider to usecloudflareNo
Cloudflare Settings
VariableDescriptionDefaultRequired if using Cloudflare
CLOUDFLARE_TOKENCloudflare API token with DNS edit permissions-Yes
CLOUDFLARE_ZONEYour domain name (e.g., example.com)-Yes
DigitalOcean Settings
VariableDescriptionDefaultRequired if using DigitalOcean
DO_TOKENDigitalOcean API token with write access-Yes
DO_DOMAINYour domain name (e.g., example.com)-Yes
Traefik API Settings
VariableDescriptionDefaultRequired
TRAEFIK_API_URLURL to Traefik APIhttp://traefik:8080/apiNo
TRAEFIK_API_USERNAMEUsername for Traefik API basic auth-No
TRAEFIK_API_PASSWORDPassword for Traefik API basic auth-No
DNS Default Settings
VariableDescriptionDefaultRequired
DNS_LABEL_PREFIXBase prefix for DNS labelsdns.No
DNS_DEFAULT_TYPEDefault DNS record typeCNAMENo
DNS_DEFAULT_CONTENTDefault record contentValue of CLOUDFLARE_ZONE or DO_DOMAINNo
DNS_DEFAULT_PROXIEDDefault Cloudflare proxy statustrueNo
DNS_DEFAULT_TTLDefault TTL in seconds1 (Auto for Cloudflare) or minimum TTL for providerNo
DNS_DEFAULT_MANAGEGlobal DNS management modetrueNo
IP Address Settings
VariableDescriptionDefaultRequired
PUBLIC_IPManual override for public IPv4Auto-detectedNo
PUBLIC_IPV6Manual override for public IPv6Auto-detectedNo
IP_REFRESH_INTERVALHow often to refresh IP (ms)3600000 (1 hour)No
Application Behaviour
VariableDescriptionDefaultRequired
POLL_INTERVALHow often to poll Traefik API (ms)60000 (1 min)No
WATCH_DOCKER_EVENTSWhether to watch Docker eventstrueNo
CLEANUP_ORPHANEDWhether to remove orphaned DNS recordsfalseNo
PRESERVED_HOSTNAMESComma-separated list of hostnames to exclude from cleanup-No
DOCKER_SOCKETPath to Docker socket/var/run/docker.sockNo
LOG_LEVELLogging verbosity (ERROR, WARN, INFO, DEBUG, TRACE)INFONo
DNS_CACHE_REFRESH_INTERVALHow often to refresh DNS cache (ms)3600000 (1 hour)No

Automated Cleanup of Orphaned Records

When containers are removed, their DNS records can be automatically cleaned up by enabling the CLEANUP_ORPHANED setting:

environment:
  - CLEANUP_ORPHANED=true

This will:

  • Track all active hostnames being managed
  • Compare them with existing DNS records
  • Remove any records that no longer match active hostnames
  • Skip system records (NS, SOA, CAA) and apex domain records

To avoid premature deletion, the system will:

  • Perform hostname normalisation to ensure case-insensitive comparison
  • Skip records that don't match the managed domain pattern
  • Only delete records that were created by this tool
  • Log all orphaned records before deletion for verification
Preserving Specific DNS Records

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:

  • Exact hostnames (e.g., api.example.com)
  • Wildcard subdomains (e.g., *.admin.example.com) which will preserve all subdomains that match the pattern

Preserved hostnames will be logged during startup and skipped during any cleanup operations.

DNS Record Tracking

The application maintains a persistent record of all DNS entries it creates in a JSON file dns-records.json. This enables:

  1. Provider Independence: Consistent tracking across different DNS providers (Cloudflare, DigitalOcean)
  2. Safety: Only records created by the tool are ever deleted during cleanup
  3. Persistence: Record history is maintained between application restarts

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

DNS Management Modes

TraeDnsManager supports two operational modes for DNS management:

Opt-out Mode (Default)
  • Set DNS_DEFAULT_MANAGE=true or leave it unset
  • All services automatically get DNS records created
  • Services can opt-out with dns.skip=true or dns.<provider>.skip=true label
Opt-in Mode
  • Set DNS_DEFAULT_MANAGE=false
  • Services need to explicitly opt-in with dns.manage=true or dns.<provider>.manage=true label
  • Services can still use skip labels to ensure no DNS management

Logging System

The application includes a configurable logging system to help with monitoring and troubleshooting:

Log Levels
  • ERROR - Only critical errors that break functionality
  • WARN - Important warnings that don't break functionality
  • INFO - Key operational information (default)
  • DEBUG - Detailed information for troubleshooting
  • TRACE - Extremely detailed information for deep troubleshooting

The 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.

INFO Level Format
✅ 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

Performance Optimisation

The application includes built-in performance optimisations to reduce API calls and improve efficiency:

DNS Caching

DNS records from providers are cached in memory to reduce API calls:

  • All records are fetched in a single API call
  • The cache is refreshed periodically (default: every hour)
  • The refresh interval can be adjusted with the DNS_CACHE_REFRESH_INTERVAL variable
Batch Processing

DNS record updates are processed in batches:

  • All hostname configurations are collected first
  • Records are compared against the cache in memory
  • Only records that need changes receive API calls
  • All other records use cached data

This significantly reduces API calls to DNS providers, especially for deployments with many hostnames.

Automatic Apex Domain Handling

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.

Building from Source

# 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

Licence

MIT

Tag summary

Content type

Image

Digest

sha256:619abc751

Size

70.3 MB

Last updated

5 months ago

docker pull eafxx/trafegodns:pr-363-v2-20260208