MarlBurroW
cloudflare-dns-swarm
TypeScript

๐ŸŒ Automatic DNS record management for Docker containers and Swarm services using Cloudflare. Label your containers, get DNS records.

Last updated Dec 9, 2025
35
Stars
1
Forks
1
Issues
0
Stars/day
Attention Score
4
Language breakdown
TypeScript 99.3%
Dockerfile 0.7%
โ–ธ Files click to expand
README

๐ŸŒ Docker/Swarm Cloudflare DNS Manager (WIP)

A Node.js service that automatically manages DNS records in Cloudflare based on Docker events. It monitors both Docker containers and Swarm services for specific labels and updates corresponding DNS records.

Tests codecov Docker Build & Push Docker Pulls License: MIT GitHub release (latest by date)

โœจ Features

  • ๐Ÿ”„ Automatic DNS record management based on Docker service labels
  • ๐Ÿ‘€ Real-time monitoring of both Docker containers and Swarm services events
  • ๐Ÿท๏ธ Support for multiple DNS record types (A, AAAA, CNAME, MX, TXT)
  • ๐Ÿš€ Public IP caching and validation
  • ๐Ÿ’ช Fault-tolerant design with retry mechanisms
  • ๐Ÿ”— Automatic DNS creation from Traefik labels (optional)

๐Ÿ“‹ Prerequisites

  • ๐Ÿ“ฆ Node.js 20 or higher
  • ๐Ÿณ Docker (works in both Swarm and standalone mode)
  • โ˜๏ธ Cloudflare account and API token with DNS edit permissions
  • ๐Ÿ”Œ Access to Docker socket (read-only is sufficient)

๐Ÿš€ Installation

Quick Start with Docker Swarm

# Create a config file for environment variables
cat << EOF > cloudflare-dns.env
CLOUDFLARETOKEN=yourcloudflareapitoken
LOG_LEVEL=info
EOF

Deploy the service to your swarm

docker service create \ --name cloudflare-dns \ --env-file cloudflare-dns.env \ --mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock,ro \ --constraint 'node.role == manager' \ marlburrow/cloudflare-dns-swarm

Or using a stack file (for Portainer or docker stack deploy):

version: "3.8"

services: dns-manager: image: marlburrow/cloudflare-dns-swarm:latest environment: - CLOUDFLARETOKEN=yourcloudflareapitoken - LOG_LEVEL=info - RETRY_ATTEMPTS=3 - RETRY_DELAY=300000 - IPCHECKINTERVAL=3600000 volumes: - /var/run/docker.sock:/var/run/docker.sock:ro deploy: mode: replicated replicas: 1 placement: constraints: - node.role == manager resources: limits: memory: 256M reservations: memory: 128M restart_policy: condition: any delay: 5s max_attempts: 3 window: 120s

Save this as cloudflare-dns-stack.yml and deploy:

docker stack deploy -c cloudflare-dns-stack.yml cloudflare-dns

๐Ÿ“– Usage

Works with both Docker containers and Swarm services. Here are examples for both:

๐Ÿท๏ธ Available Labels

  • dns.cloudflare.hostname: DNS record name (required)
  • dns.cloudflare.type: Record type (A, AAAA, CNAME, TXT, MX)
  • dns.cloudflare.content: Record content (required for CNAME, optional for A/AAAA)
  • dns.cloudflare.ttl: Time to live in seconds (optional, default: 1)
  • dns.cloudflare.proxied: Enable/disable Cloudflare proxy (optional, default: true)

๐ŸŽฏ Default Behaviors

The service includes smart defaults to minimize configuration:

  • ๐Ÿ”ค Record Type: If not specified, defaults to A record
  • ๐ŸŒ Record Content:
- For A records: Uses public IP from ipify.org if not specified - For AAAA records: Uses public IPv6 if available, else skips record creation - For other types (CNAME, TXT, MX): Content is required
  • โšก Proxy Status: Defaults to true (traffic proxied through Cloudflare)
  • โฑ๏ธ TTL: Defaults to 1 (automatic)
Example with minimal configuration:
# Only hostname specified - creates an A record with public IP
docker service create \
  --name my-service \
  --label dns.cloudflare.hostname=api.domain.com \
  your-image

๐Ÿ“ฆ Docker Container

# Create a container with DNS records
docker run -d \
  --name my-container \
  --label dns.cloudflare.hostname=api.domain.com \
  --label dns.cloudflare.type=A \
  --label dns.cloudflare.proxied=false \
  your-image

๐Ÿณ Docker Swarm Service

๐Ÿ”น Basic A Record

# Create a service with an A record and custom TTL
docker service create \
  --name my-service \
  --label dns.cloudflare.hostname=subdomain.domain.com \
  --label dns.cloudflare.type=A \
  --label dns.cloudflare.ttl=3600 \
  your-image

๐Ÿ”„ CNAME Record

# Create a service with a CNAME record
docker service create \
  --name my-service \
  --label dns.cloudflare.hostname=alias.domain.com \
  --label dns.cloudflare.type=CNAME \
  --label dns.cloudflare.content=target.domain.com \
  --label dns.cloudflare.proxied=true \
  your-image

๐ŸŒ IPv4 and IPv6 Records

# Create a service with both A and AAAA records
docker service create \
  --name my-service \
  --label dns.cloudflare.hostname=api.domain.com \
  --label dns.cloudflare.type=A \
  --label dns.cloudflare.proxied=true \
  --label dns.cloudflare.hostname.v6=api.domain.com \
  --label dns.cloudflare.type.v6=AAAA \
  --label dns.cloudflare.content.v6=2001:db8::1 \
  --label dns.cloudflare.proxied.v6=false \
  your-image

๐Ÿท๏ธ Multiple Subdomains

# Create a service with multiple subdomains
docker service create \
  --name my-service \
  --label dns.cloudflare.hostname=api.domain.com \
  --label dns.cloudflare.type=A \
  --label dns.cloudflare.hostname.admin=admin.domain.com \
  --label dns.cloudflare.type.admin=A \
  --label dns.cloudflare.hostname.web=www.domain.com \
  --label dns.cloudflare.type.web=CNAME \
  --label dns.cloudflare.content.web=domain.com \
  your-image

๐Ÿ”€ Multiple Records

# Create a service with mixed record types
docker service create \
  --name my-service \
  --label dns.cloudflare.hostname=domain.com \
  --label dns.cloudflare.type=A \
  --label dns.cloudflare.hostname.mx=domain.com \
  --label dns.cloudflare.type.mx=MX \
  --label dns.cloudflare.content.mx="10 mail.domain.com" \
  --label dns.cloudflare.hostname.txt=domain.com \
  --label dns.cloudflare.type.txt=TXT \
  --label dns.cloudflare.content.txt="v=spf1 include:_spf.domain.com ~all" \
  your-image

โš™๏ธ Configuration

The following environment variables can be used to configure the application:

Core Settings

| Variable | Description | Default | Required | | ------------------- | ---------------------------------------- | ---------------------- | -------- | | CLOUDFLARE_TOKEN | Cloudflare API token | - | Yes | | DOCKER_SOCKET | Docker socket path | /var/run/docker.sock | No | | LOG_LEVEL | Logging level (debug, info, warn, error) | info | No | | RETRY_ATTEMPTS | Number of retry attempts | 3 | No | | RETRY_DELAY | Delay between retries (ms) | 300000 | No | | IPCHECKINTERVAL | IP check interval (ms) | 3600000 | No |

DNS Settings

| Variable | Description | Default | Required | | ------------------------- | ------------------------------- | ------- | -------- | | USETRAEFIKLABELS | Enable Traefik label support | false | No | | DNSDEFAULTRECORD_TYPE | Default DNS record type | A | No | | DNSDEFAULTCONTENT | Default record content | - | No | | DNSDEFAULTPROXIED | Default Cloudflare proxy status | true | No | | DNSDEFAULTTTL | Default TTL | 1 | No |

Examples

Basic Configuration

CLOUDFLARETOKEN=yourtoken_here
USETRAEFIKLABELS=true
DNSDEFAULTRECORD_TYPE=A
DNSDEFAULTPROXIED=true

CNAME Configuration

DNSDEFAULTRECORD_TYPE=CNAME
DNSDEFAULTCONTENT=origin.domain.com
DNSDEFAULTPROXIED=false
DNSDEFAULTTTL=3600

๐Ÿ”— Traefik Integration

The service can automatically create DNS records from your Traefik Host rules.

Important Notes

  • Traefik integration must be explicitly enabled with USETRAEFIKLABELS=true
  • DNS records are only created for services with traefik.enable=true
  • DNS settings can be overridden using explicit dns.cloudflare.\* labels
  • Multiple hosts in a single rule are supported and will create separate DNS records
  • CNAME records require explicit content to be specified

Configuration

Enable Traefik integration and configure default behavior:

# Enable Traefik integration
USETRAEFIKLABELS=true

Configure default DNS settings (optional)

DNSDEFAULTRECORD_TYPE=A DNSDEFAULTCONTENT= DNSDEFAULTPROXIED=true DNSDEFAULTTTL=1

Examples

Basic Usage

services:
  webapp:
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.webapp.rule=Host(app.domain.com)"
      # This will create:
      # - An A record for app.domain.com
      # - Using your public IP as content
      # - With Cloudflare proxy enabled

Custom DNS Settings

services:
  webapp:
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.webapp.rule=Host(app.domain.com)"
      # Override default DNS settings
      - "dns.cloudflare.type=CNAME"
      - "dns.cloudflare.content=origin.domain.com"
      - "dns.cloudflare.proxied=false"

Multiple Hosts

services:
  webapp:
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.webapp.rule=Host(app.domain.com) || Host(api.domain.com)"
      # This will create DNS records for both domains
      # using the default settings

Development Setup

If you want to contribute or modify the code:

  • Clone the repository:
git clone https://github.com/yourusername/docker-swarm-dns-manager.git
cd docker-swarm-dns-manager
  • Copy .env.example to .env and fill in your Cloudflare credentials:
cp .env.example .env
  • Install dependencies and start in development mode:
yarn install
yarn dev

Or using docker-compose for development:

docker compose up -d

The development setup includes:

  • Hot reloading for code changes
  • Debug level logging
  • Source maps for debugging

๐Ÿงช Testing

The project uses Jest for testing. The test suite includes:

  • Unit tests for all services and utilities
  • Integration tests for Docker events and DNS updates
  • Validation tests for labels and configurations
  • Mock implementations for external services (Docker, Cloudflare, IP services)
To run the tests:
# Run tests
yarn test

Run tests in watch mode

yarn test:watch

Run tests with coverage report

yarn test:coverage

๐Ÿ”’ Error Handling & Reliability

Based on the test suite, the service includes:

  • Automatic retries for failed DNS operations
  • IP address validation and double-checking
  • Graceful handling of Docker event failures
  • Caching of IP addresses with periodic refresh
  • Validation of all DNS record configurations
  • Fault tolerance for network issues
Current test coverage: codecov

The project maintains a high test coverage to ensure reliability. All new contributions should include appropriate tests.

๐Ÿค Contributing

Contributions are welcome! Feel free to open an issue or pull request.

๐Ÿ—บ๏ธ Roadmap

๐ŸŽฏ Upcoming Features

๐Ÿ”„ Multi-Provider Support

The next major version will introduce a plugin system for multiple DNS providers:

  • ๐Ÿ”Œ Plugin Architecture
- Abstract provider interface - Easy integration of new providers - Hot-swappable providers
  • ๐Ÿข Planned Providers
- โœ… Cloudflare (current) - ๐Ÿ”œ AWS Route53 - ๐Ÿ”œ Google Cloud DNS - ๐Ÿ”œ OVH DNS - ๐Ÿ”œ Digital Ocean DNS

Want to contribute to these features? Check our Contributing section!

๐Ÿ“„ License

MIT

๐Ÿ”— More in this category

ยฉ 2026 GitRepoTrend ยท MarlBurroW/cloudflare-dns-swarm ยท Updated daily from GitHub