# favonia/cloudflare-ddns: a Go DDNS updater for Cloudflare DNS records

> A Docker-first updater that detects your public IPv4 and IPv6 addresses and writes them into Cloudflare A and AAAA records, with WAF list maintenance and failure notifications. Its design is careful, but it is Cloudflare-only and not the tool for every network.

**favonia/cloudflare-ddns** — 🌟 A small, feature-rich, and robust Cloudflare DDNS updater

- Repository: https://github.com/favonia/cloudflare-ddns
- Stars: 2,914 · Forks: 117
- Language: Go
- License: Apache-2.0
- Published: 2026-09-28 · Updated: 2026-09-28 · Language: en
- Canonical page: https://hysenlabs.com/projects/favonia-cloudflare-ddns

## The problem favonia/cloudflare-ddns solves, and for whom

Home and small-office connections rarely keep the same public address for long. A dynamic DNS client watches that address and pushes it into a DNS record so that a hostname keeps pointing at the right machine. favonia/cloudflare-ddns does that job specifically for Cloudflare: it detects the machine's public IPv4 and IPv6 addresses and updates DNS records through the Cloudflare API.

The intended user runs something that must stay reachable by name on a connection with a shifting address, and already has the domain on Cloudflare. The README lists a small Docker image and describes the project as feature-rich and robust. The repository is written in Go, licensed Apache-2.0, and the last push was on 2026-09-24, with release 1.17.1 published on 2026-09-20. That is a maintained project by any reasonable reading, though the maintainer's own design documents are the better guide to how it behaves than any activity signal.

The audience is narrower than "anyone who needs DDNS". If your DNS is not on Cloudflare, nothing here applies. If your router firmware has a built-in DDNS client for another provider, this container adds a dependency rather than removing one.

## How the updater works: detection, reconciliation, and caching

Two loops matter. One detects the public address. The other reconciles DNS records against that address.

Detection is pluggable. By default, public IP detection stays with Cloudflare: the cloudflare.trace provider contacts HTTPS trace endpoints operated by Cloudflare, which the updater already talks to when writing records. The README states that by default the updater uses only HTTPS or DNS over HTTPS for detection, and points to a design document on the network security model for the reasoning. That choice is deliberate: an attacker who can spoof a plaintext detection response could push a wrong address into your records.

Reconciliation is where the Cloudflare specifics show. The updater preserves existing proxy statuses, TTLs, and comments for records it manages, and you can set fallback values for cases where it must supply them. It accepts domain lists without requiring you to know the DNS zone, handles internationalized domain names and wildcards, and lets you toggle IPv4 A records and IPv6 AAAA records per domain. Cloudflare API responses are cached in memory to reduce API usage, which is why the go.mod pulls in jellydator/ttlcache.

Transient network failures are expected rather than exceptional. The dependency list includes hashicorp/go-retryablehttp, and the README describes the updater as designed to recover from transient network failures. Retries with exponential backoff are the mechanism; the README does not spell out the retry count or backoff schedule, so treat those as implementation details to read in the source if they matter to you.

## Installing favonia/cloudflare-ddns and running a first update

The README's quick start runs the Docker image directly. First create a Cloudflare API token from the API Tokens page with the Zone - DNS - Edit and Account - Account Filter Lists - Edit permissions. The README notes you can remove unneeded permissions based on your setup, so a DNS-only deployment does not need the list permission.

Pass the token and the domains you want managed as environment variables. The README's quick start shows the shape of the command:

```bash
docker run \
  -e CLOUDFLARE_API_TOKEN=your_token_here \
  -e DOMAINS=www.a.org,hello.io \
  favonia/cloudflare-ddns:1
```

The updater starts, detects the public address, and writes the corresponding A or AAAA records. Domains are given as a plain comma-separated list; you do not need to specify zones. Expect log output describing detection and the record updates it performs.

For a long-running deployment, a compose file is the more common route, and the repository's topics include docker-compose. The README's quick start section is the authoritative source for the exact variable names and any additional options; consult it rather than copying a snippet from elsewhere.

If you would rather not trust an image tag, the README documents cosign verification:

```bash
cosign verify favonia/cloudflare-ddns:1 \
  --certificate-identity-regexp https://github.com/favonia/cloudflare-ddns/ \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com
```

A GHCR mirror exists since version 1.17.1 and can be verified with the same command by replacing the image reference with ghcr.io/favonia/cloudflare-ddns:1. The README is explicit that this proves the image came from the repository, not that the code is secure.

## WAF lists and failure notifications

Two features separate this from a minimal A-record updater.

The updater can maintain Cloudflare lists of detected IP addresses. The README calls them WAF lists, but notes their use is not limited to the WAF: any Cloudflare product that consumes the Rules language can reference them, including Cloudflare Rules. That matters if you gate origin access by source address, because the list follows your address without you editing firewall rules by hand. It also means the API token needs the Account - Account Filter Lists - Edit permission, which is a broader grant than DNS editing alone.

For failure visibility, the updater can report to Healthchecks or Uptime Kuma, so a failed update produces a notification rather than silence. Separately, it can send updates through any service supported by the shoutrrr library, which the README describes as covering email, major notification services, major messaging platforms, and generic webhooks. The distinction is worth keeping: Healthchecks and Uptime Kuma are heartbeat-style monitors that alert on absence, while shoutrrr is a general delivery library. Choosing one over the other changes what kind of failure you actually learn about.

## Where favonia/cloudflare-ddns is the wrong tool

The obvious limitation is the one in the name. Every record update goes through the Cloudflare API, and the token scopes are Cloudflare-specific. If you host DNS at another provider, or you want one updater across several providers, this is not it.

A second limitation is the container requirement for the documented path. The quick start is Docker. The Dockerfile builds a static binary and produces both an alpine-based image for debugging network issues and a scratch-based minimal image, and the README highlights the small image size. A Go binary is technically portable, but the README does not document installing it outside the container, so treat the container as the supported deployment.

Third, the default detection provider contacts Cloudflare trace endpoints. The README frames this as a privacy choice, since the updater already contacts Cloudflare for DNS updates, and it is a defensible one. It still means your public address is disclosed to Cloudflare through a second channel, and if that is unacceptable you must configure a different detection provider. The README points to the IP Detection section for the current endpoint list rather than pinning it in the highlights.

Finally, cost. The project itself is Apache-2.0 and free to run, but it manages records on Cloudflare, and the README says nothing about which Cloudflare plan you need. Questions about whether Cloudflare dynamic DNS is free are about Cloudflare's own terms, not this project's licence.

## Alternatives and how they differ

The search data around this project is full of comparison queries, which reflects a real fork in the road.

ddclient is the long-standing general-purpose client. The difference is architectural: ddclient supports many DNS providers through per-provider configuration, while favonia/cloudflare-ddns targets one API and spends its complexity on Cloudflare semantics such as preserved proxy status, TTL, and comments, plus WAF list maintenance. If you need two providers, ddclient is the safer bet. If you need one provider and want the Cloudflare-specific behaviour, the narrower tool does more.

DuckDNS and NoIP are hosted DDNS services rather than clients. They give you a hostname under their own domain and run the DNS side for you, so you point a CNAME at it instead of updating records in your own zone. That is less control and a different trust relationship, but it avoids both the API token and the container.

Cloudflare Tunnel is the alternative that changes the problem rather than the client. A tunnel makes an outbound connection from your network to Cloudflare, so the origin is reachable without publishing your address in a DNS record at all. For HTTP services this is often the better answer, because there is no address to keep current. It does not help for arbitrary TCP or UDP services, which is exactly where a DDNS updater still earns its place.

Oznu/cloudflare-ddns appears in the same searches as another Cloudflare-focused option. The two occupy the same niche; the documentation here covers only favonia's implementation, so compare their configuration surfaces directly if you are choosing between them.

## Maintenance, upgrades, and licence

The project is not archived and the last push was on 2026-09-24. Releases are tagged, with 1.17.1 on 2026-09-20, 1.17.0 on 2026-07-28, and 1.16.2 on 2026-04-02. The cadence is irregular rather than monthly, which is normal for a tool this size.

Upgrade cost is low by design. The README's examples pin the major tag, favonia/cloudflare-ddns:1, so pulling that tag moves you across minor versions. If you want to control that, pin the full version instead. The go.mod carries retract directives, including v1.14.1 for a nil pointer bug and the range up to v1.7.99 for incompatible templates for PROXIED handling. Retractions are a signal worth reading before you jump across a large version gap: they tell you which releases the maintainer considers unsafe to fetch.

The Cloudflare API is the external dependency that can break you. The README states that compatibility with the Cloudflare API is verified periodically with dedicated scripts under scripts/, which is a stronger position than most small updaters take. It is still a periodic check, not a guarantee.

The licence is Apache-2.0. That permits commercial use and modification, and it includes an explicit patent grant and a patent retaliation clause. It also requires that you preserve notices and state significant changes if you redistribute. Docker image distribution and running the binary internally are unaffected. This is a description of the licence text, not legal advice; read LICENSE in the repository if your situation is unusual.

## Conclusion

Adopt favonia/cloudflare-ddns if your DNS already lives on Cloudflare and you want a container that keeps A and AAAA records current without hand-written scripts. Do not adopt it if you need a provider-agnostic updater, or if your router firmware cannot run a container or a Go binary. Before deploying, verify that your API token carries only the permissions your setup needs and check the current endpoint list under IP Detection, because the default detection provider contacts Cloudflare trace endpoints.

## FAQ

### How do I install favonia/cloudflare-ddns?

The documented path is Docker. Create a Cloudflare API token with the Zone - DNS - Edit permission (and Account - Account Filter Lists - Edit if you use WAF lists), then run the favonia/cloudflare-ddns:1 image with the token and a DOMAINS list passed as environment variables. The README's quick start section has the exact command.

### How do I set up favonia/cloudflare-ddns on UniFi?

The README documents Docker as the deployment path, and the repository topics include Docker and docker-compose. Running a container on UniFi hardware depends on the firmware and is not covered in the project's documentation, so check whether your device can run the image before planning around it.

### What does favonia/cloudflare-ddns do?

It detects the machine's public IPv4 and IPv6 addresses and updates DNS records through the Cloudflare API. It can also maintain Cloudflare lists of detected addresses and report failures to Healthchecks, Uptime Kuma, or a shoutrrr-supported notification service.

### Can I use Cloudflare for DDNS?

Yes, through the Cloudflare API. favonia/cloudflare-ddns is one client that does this: it writes A and AAAA records for the domains you list, preserving existing proxy status, TTL, and comments for the records it manages.

### How do I use favonia/cloudflare-ddns?

Run the Docker image with a Cloudflare API token and a DOMAINS list, and the updater detects the public address and writes the matching A and AAAA records. The README's quick start covers the token permissions and the environment variables.

## Sources

- [favonia/cloudflare-ddns on GitHub](https://github.com/favonia/cloudflare-ddns)
- [Issues](https://github.com/favonia/cloudflare-ddns/issues)
- [License: Apache-2.0](https://github.com/favonia/cloudflare-ddns/blob/main/LICENSE)
- [README](https://github.com/favonia/cloudflare-ddns/blob/main/README.md)
- [Releases](https://github.com/favonia/cloudflare-ddns/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/favonia-cloudflare-ddns
