A minimal Cloudflare Dynamic DNS client written in Go. No dependencies, single binary, configured entirely via environment variables.
How it works: Detect public IP → Compare with Cloudflare DNS → Update if changed
- Auto-selects IP detection service based on record type (IPv4 or IPv6 endpoints of icanhazip / ifconfig.co / ipify)
- Remembers the last successful service to minimize latency
- Only calls Cloudflare API when IP actually changes
- IPv4 (
A) and IPv6 (AAAA) support - Single-run mode for cron jobs
- Go 1.18+ (or use Docker )
- Access to Cloudflare API
All configuration is done via environment variables:
| Variable | Required | Description |
|---|---|---|
CF_API_TOKEN |
✅ | Cloudflare API token (DNS edit permission) |
CF_ZONE_ID |
✅ | Cloudflare Zone ID |
CF_RECORD_NAME |
✅ | DNS record to update, e.g. home.example.com |
CF_RECORD_TYPE |
✅ | A (IPv4) or AAAA (IPv6) |
CF_CHECK_INTERVAL |
— | Check interval in seconds (default: 300) |
CF_TTL |
— | DNS TTL in seconds (default: inherits existing record) |
CF_PROXIED |
— | true or false (default: inherits existing record) |
CF_IP_URLS |
— | Comma-separated IP detection service URLs (default: built-in list, auto-selected based on CF_RECORD_TYPE) |
export CF_API_TOKEN=your-token
export CF_ZONE_ID=your-zone-id
export CF_RECORD_NAME=home.example.com
export CF_RECORD_TYPE=A
go run main.gogo build -o scfddns .
./scfddns./scfddns -onceIf using a proxy, add
*.ipify.org,ifconfig.co,*.icanhazip.comto your bypass list.
docker run -d \
--name cloudflare-ddns \
--restart unless-stopped \
-e CF_API_TOKEN=your-token \
-e CF_ZONE_ID=your-zone-id \
-e CF_RECORD_NAME=home.example.com \
-e CF_RECORD_TYPE=A \
betterlmy/simple-cloudflare-ddns:latestCreate a .env file:
CF_API_TOKEN=your-token
CF_ZONE_ID=your-zone-id
CF_RECORD_NAME=home.example.com
CF_RECORD_TYPE=AThen run:
docker-compose up -dgit clone https://github.com/betterlmy/simple-cloudflare-ddns.git
cd simple-cloudflare-ddns
docker build -t simple-cloudflare-ddns:latest .- Runs as non-root user
- Multi-arch: AMD64 and ARM64
- Alpine-based (~20MB)
| Flag | Description |
|---|---|
-once |
Run once and exit (suitable for cron) |
- Go to Cloudflare API Tokens
- Click "Create Token" → "Edit zone DNS" → "Use template"

- Set permissions:
Zone:DNS:Edit, select your zone
- Copy the generated token
- Go to Cloudflare Dashboard
- Select your domain
- Find "Zone ID" in the bottom-right of the Overview page

Can't get public IP?
- The program tries multiple services automatically
- If all fail, check your network connection or proxy bypass list
- Restart the program to retry
DNS update not taking effect?
- Verify
CF_ZONE_ID,CF_RECORD_NAME, andCF_RECORD_TYPEare correct - Check that the API token has DNS edit permission
- Make sure there's no conflicting record of a different type in Cloudflare
Updates too frequent?
- Increase
CF_CHECK_INTERVAL(recommended: 300–600 seconds for home users)
MIT License
⭐ If you find it useful, please give a Star!