Small containerized DDNS service for Cloudflare.
1.4K
Small containerized DDNS service for Cloudflare.
It periodically checks your public IP and keeps one or more A records in a Cloudflare zone pointing at that IP. It also exposes a small HTTP health endpoint and integrates with Docker’s HEALTHCHECK.
Typical use case: home servers with a dynamic IP, using Cloudflare as DNS.
/healthz) and Docker HEALTHCHECKexample.com, xyz.example.com)Note: This tool currently manages A records (IPv4) only.
https://checkip.amazonaws.com).xyz.example.com):
In addition to reacting to IP changes, it also ensures that records stay correct even if someone edits them manually in the Cloudflare dashboard.
Required:
CF_API_TOKEN - Cloudflare API token, scoped to the specific zone you want to manage:
Zone → DNS → Edit (Optionally Zone → Zone → Read)CF_ZONE_NAME - Your Cloudflare zone, e.g.: example.com
CF_RECORDS - Comma-separated list of records to manage. Each entry can be:
xyz → becomes xyz.example.comxyz.example.com@ or example.com for the zone apexOptional:
CHECK_INTERVAL
How often to check/update (in seconds).
Default: 300 (5 minutes)
CF_TTL
TTL to set on updated records.
Default: 120
CF_PROXIED
Whether to set proxied to true or false on updated A records:
false → DNS only
true → use Cloudflare proxy (for typical HTTP services). Default: false
Accepted values:
true,false,1,0,yes,no
IP_DISCOVERY_URL
URL returning your public IP as plain text.
Default: https://checkip.amazonaws.com
HEALTH_PORT
Port for the internal HTTP health server.
Default: 8080
The container runs a small HTTP server on 0.0.0.0:$HEALTH_PORT (default 8080) with:
GET /healthzGET /healthGET /Example response:
{
"status": "ok",
"current_ip": "203.0.113.42",
"last_check": 1733300000.0,
"last_success": 1733300000.0,
"last_change": 1733299900.0,
"last_error": null
}
status values:
starting – service is initializing / hasn’t successfully synced yetok – last run succeedederror – last run encountered an error (see last_error)You can optionally map this port to the host for scraping or debugging:
curl http://127.0.0.1:8080/healthz
services:
cloudflare-ddns:
image: fviolence/cloudflare-ddns:latest
container_name: cloudflare-ddns
restart: unless-stopped
environment:
CF_API_TOKEN: "${CF_API_TOKEN}"
CF_ZONE_NAME: "example.com"
CF_RECORDS: "xyz"
CHECK_INTERVAL: "300"
CF_TTL: "120"
CF_PROXIED: "false"
HEALTH_PORT: "8080"
# Optionally expose the health endpoint on the host:
# ports:
# - "127.0.0.1:8080:8080"
To verify DNS:
dig A xyz.example.com +short
If you change the A record manually in the Cloudflare UI, the container will correct it on the next loop to match your current public IP.
CF_PROXIED setting for all managed records.The Git repository for all the sources and Dockerfile.
Content type
Image
Digest
sha256:4cb2b85b9…
Size
45.4 MB
Last updated
4 months ago
docker pull fviolence/cloudflare-ddns