Quick Reference:
Git repo: https://github.com/mathat13/cloudflare-ddns-updater
Where to file issues: https://github.com/mathat13/cloudflare-ddns-updater/issues
Maintained by: mathat13
Versioning
Image overview:
Hello and welcome to my image, this is the first image that I have published and as such, will most likely not be suitable for enterprise solutions, but should be suitable for any home user. There are many alternatives to this image that accomplish the same task, mine is designed to be as simple as possible, so that it can be set up easily and forgotten about while it accomplishes it's task. Now even simpler! This image currently supports A records only and no subdomain support yet, possibly in a future update. But this shouldn't matter if you only want to keep the external IP of your network up to date on CloudFlare.
Who is this image for?
This image is for any home lab hobbyist to be able to set up their own DDNS with as little hassle as possible. I have tried to minimize the amount of things you will need to get started, please see section ‘Things that you will need’ below for further details.
What problem does this image solve?
This image is designed to update the IP record of your domain's external IP on your Cloudflare DNS account through the CloudFlare API. This is designed for a user who wishes to set up their own website/ other services that they would like to expose to the internet. One of the problems that some users, including myself, experience is that whenever their router is reset, there's a chance that the external IP of their network will change! This is not ideal as the usual way to update the IP of your network on CloudFlare is manually, meaning that you would have to notice that the IP had changed to begin with, perhaps with a rude text message from one of your website's users, then log in to your CloudFlare account and update the DNS A record so that it matches your current external IP, this would unfortunately mean that none of your service's users could access your services until this has happened. This image basically monitors your network's external IP and then automatically updates CloudFlare whenever there is a change, so that you can sit back, relax and confidently avoid any further rude messages, at least for this issue.
How to use this image
As mentioned previously, this image is designed to be as simple as possible, what follows will be a list of things that you will need before you are able to run this image successfully, along with some optional useful tips.
Things that you will need:
A domain
This will be the only expense that will be required with this project, there are many domain providers to choose from but do check that you can switch your the DNS from the current provider to CloudFlare before purchasing. For simplicity, understand that a domain purchased through CloudFlare would come with the required DNS pre-packaged. Here is CloudFlare's guide to switching DNS providers to them in any case.
A machine with Docker and optionally Docker Compose available
I tend to use the Installation Script for Linux machines, Docker Compose will have to be installed seperately, instructions for Windows machines can be found here, note that Docker Compose is included in the Docker Desktop Windows installation.
The name of your domain
This is simply the text string that you want to navigate to to reach your website or service (e.g. example.com), write it in a text document.
A CloudFlare API PUT key
This will have to be generated by yourself for your account, remember that any API key is very sensitive and shouldn't be shared with anyone, lest the person will be able to do anything that this API key allows them to do. Instructions to navigate to the Create Custom API token page can be found here and the specific settings for the PUT key are shown below:

The next page will contain a string of characters that represents your API key, write this down in your text file and label it as the PUT Key.
Anything Else?
That's it! Previously, you would need to find your domain Zone ID, create the A record for your domain manually, and create an API GET key. But The first two are now fetched dynamically and an API PUT key has the permissions of an API GET key and more, so we don't need them anymore.
Bringing it all together
Now that you have all the information needed to get this image running in a container, we will bring it all together. In this section you will learn how to set up the container so that you can set it and forget it, as well as the reference docker compose, docker run, and .env file variables that you can use. I would recommend that you put your sensitive information like API keys into the .env file and change the permissions so that only administrators can read it, each way is highlighted in this section.
Setup Instructions
I will go through these instructions on Linux but Windows will be similar:
Step 1: Browse to a sensible location and create a new folder to house the project:
mkdir cloudflare-ddns-updater && cd cloudflare-ddns-updater
Step 2: Copy the Docker Compose of your choosing in the 'Reference Information' section below and save it to a file named ‘cloudflare-ddns-updater.yml’. If you'd prefer to use a docker run command that you can just run in your shell, a minimal example can be also be found in the same place, and this step can be safely skipped.
nano cloudflare-ddns-updater.yml
Step 3 (optional): If using a .env file, you will now create it, copy and paste the template from the github repo, fill out with your values and save:
touch .env && sudo chown root:root .env && sudo chmod 600 .env && sudo nano .env
This file will be restricted so that only root can open and edit it, so remember to sudo before trying to edit or view it.
The project structure should look as below at this point if using docker compose and a .env file:

you won't actually have any files or a requirement of a project directory if using docker run without a .env file.
Step 4: Bring the container up with:
sudo docker compose -f cloudflare-ddns-updater.yml up -d
or by running the docker run command of your choosing in your shell.
Step 5: The script is set to execute every $UPDATE_FREQUENCY, so check the logs with the below command to see how it goes:
docker logs cloudflare-ddns-updater
And check that the container is running correctly with this command:
docker container ls
Reference information
Environment Variables
You will be able to find an example .env file that you can use as a template in the github repository for this image, named .env.example, I'll just go over each variable here so that you know what is possible:
| Variable | Description | Default |
|---|---|---|
DNS_RECORD_NAME |
Your domain name, you should have this in your text document (required). | — |
PUT_KEY |
API token used to authenticate against the CloudFlare API (required). | — |
TTL |
Time to Live for the record stored on CloudFlare. Default is 1 (CloudFlare "auto"). Values above 120 are supported. |
1 |
PROXIED |
Whether CloudFlare should proxy traffic through its servers. Default is false. Can improve security, but may cause issues with reverse proxies. |
false |
UPDATE_FREQUENCY |
Interval (in seconds) between checks of your external IP against the record stored on CloudFlare. | 600 |
LOG_LEVEL |
Logging verbosity. Options: 0 = Success/Failure only, 1 = Informational, 2 = Debug. |
1 |
Docker command and compose examples
No .env file
Docker run:
docker run -d \
--name cloudflare-ddns-updater \
--init \
--restart always \
--log-opt max-size=10m \
--log-opt max-file=3 \
-e DNS_RECORD_NAME=your_zone_name \
-e PUT_KEY=your_put_key \
-itd mathat13/cloudflare-ddns-updater:latest
Docker Compose:
services:
cloudflare-ddns-updater:
image: mathat13/cloudflare-ddns-updater:latest
container_name: cloudflare-ddns-updater
init: true
restart: always
logging:
options:
max-size: "10m"
max-file: "3"
environment:
- DNS_RECORD_NAME=your_zone_name
- PUT_KEY=your_put_key
Note that we will use -e/ environment: to declare environment variables in the run command/ compose file, just follow the pattern to add more environment varaibles. These will be all you need to run the container though. All supported environment variables can be found in the above 'Environment Variables' section.
With .env file:
Docker run:
docker run -d \
--name cloudflare-ddns-updater \
--init \
--restart always \
--log-opt max-size=10m \
--log-opt max-file=3 \
--env-file .env \
-itd mathat13/cloudflare-ddns-updater:latest
Docker Compose:
services:
cloudflare-ddns-updater:
image: mathat13/cloudflare-ddns-updater:latest
container_name: cloudflare-ddns-updater
init: true
restart: always
env_file:
- .env
logging:
options:
max-size: "10m"
max-file: "3"
Versioning
Versioning
This image follows Semantic Versioning (MAJOR.MINOR.PATCH):
MAJOR (2.x.x) – Breaking changes. If functionality changes in a way that requires manual intervention, the major version will increment.
MINOR (1.1.x) – Backwards-compatible improvements or new features.
PATCH (1.1.1) – Backwards-compatible bug fixes.
The latest tag always points to the most recent stable release. If you prefer to pin a specific version, all published versions are available on the Tags tab.
If you encounter issues, please raise an issue in the GitHub repository.