Program to keep DNS A and/or AAAA records updated for multiple DNS providers
This readme and the docs/ directory are versioned to match the program version:
| Version | Readme link | Docs link |
|---|---|---|
| Latest | README | docs/ |
v2.8 |
README | docs/ |
v2.7 |
README | docs/ |
v2.6 |
README | docs/ |
v2.5 |
README | docs/ |
ghcr.io/qdm12/ddns-updater and qmcgaw/ddns-updaterddns-updater - see #808Web user interface (Desktop)

Web user interface (Mobile)

Send notifications with Shoutrrr using SHOUTRRR_ADDRESSES
amd64, 386, arm64, armv7, armv6, s390x, ppc64le, riscv64 CPU architecturesgo install github.com/qdm12/ddns-updater/cmd/ddns-updater@latest.chmod +x ddns-updater.data.Write a JSON configuration in data/config.json, for example:
json
{
"settings": [
{
"provider": "namecheap",
"domain": "sub.example.com",
"password": "e5322165c1d74692bfa6d807100c0310"
}
]
}
You can find more information in the configuration section to customize it.
1. Run the program with ./ddns-updater (./ddns-updater.exe on Windows) or by double-clicking on it.
1. The following is optional.
- You can customize the program behavior using either environment variables or flags. For flags, there is a flag corresponding to each environment variable, where it's all lowercase and underscores are replaced with dashes. For example the environment variable LOG_LEVEL translates into --log-level.
Create a directory, for example, data which is:
1000, which is the built-in user ID of the ddns-updater containersh
mkdir data
chown 1000 data
chmod u+r+w+x data
If you want to use another user ID, build the image yourself with --build-arg UID=<your-uid>. You could also just run the container as root with --user="0" but this is not advised security wise.
Similarly, create a data/config.json file which is:
1000sh
touch data/config.json
chmod u+r data/config.json
Edit data/config.json, for example:
json
{
"settings": [
{
"provider": "namecheap",
"domain": "sub.example.com",
"password": "e5322165c1d74692bfa6d807100c0310"
}
]
}
You can find more information in the configuration section to customize it.
Run the container with
sh
docker run -d -p 8000:8000/tcp -v "$(pwd)"/data:/updater/data ghcr.io/qdm12/ddns-updater
The following is optional.
docker-compose up -ddocker pull ghcr.io/qdm12/ddns-updater{"settings": [{"provider": "namecheap", ...}]}), which takes precedence over config.json. Note however that if you don't bind mount the /updater/data directory, there won't be a persistent database file /updater/updates.json but it will still work.Start by having the following content in config.json, or in your CONFIG environment variable:
{
"settings": [
{
"provider": "",
},
{
"provider": "",
}
]
}
For each setting, you need to fill in parameters. Check the documentation for your DNS provider:
Note that:
"domain": "example.com,sub.example.com,sub2.example.com",.
⚠️ this is a bit different for DuckDNS and GoIP, see their respective documentation.🆕 There are now flags equivalent for each variable below, for example --log-level.
| Environment variable | Default | Description |
|---|---|---|
CONFIG |
One line JSON object containing the entire config (takes precedence over config.json file) if specified | |
PERIOD |
5m |
Default period of IP address check, following this format |
PUBLICIP_FETCHERS |
all |
Comma separated fetcher types to obtain the public IP address from http and dns |
PUBLICIP_HTTP_PROVIDERS |
all |
Comma separated providers to obtain the public IP address (ipv4 or ipv6). See the Public IP section |
PUBLICIPV4_HTTP_PROVIDERS |
all |
Comma separated providers to obtain the public IPv4 address only. See the Public IP section |
PUBLICIPV6_HTTP_PROVIDERS |
all |
Comma separated providers to obtain the public IPv6 address only. See the Public IP section |
PUBLICIP_DNS_PROVIDERS |
all |
Comma separated providers to obtain the public IP address (IPv4 and/or IPv6). See the Public IP section |
PUBLICIP_DNS_TIMEOUT |
3s |
Public IP DNS query timeout |
UPDATE_COOLDOWN_PERIOD |
5m |
Duration to cooldown between updates for each record. This is useful to avoid being rate limited or banned. |
HTTP_TIMEOUT |
10s |
Timeout for all HTTP requests |
SERVER_ENABLED |
yes |
Enable the web server and web UI |
LISTENING_ADDRESS |
:8000 |
Internal TCP listening port for the web UI |
ROOT_URL |
/ |
URL path to append to all paths to the webUI (i.e. /ddns for accessing https://example.com/ddns through a proxy) |
HEALTH_SERVER_ADDRESS |
127.0.0.1:9999 |
Health server listening address |
HEALTH_HEALTHCHECKSIO_BASE_URL |
https://hc-ping.com |
Base URL for the healthchecks.io server |
HEALTH_HEALTHCHECKSIO_UUID |
UUID to idenfity with the healthchecks.io server | |
DATADIR |
/updater/data |
Directory to read and write data files from internally |
CONFIG_FILEPATH |
/updater/data/config.json |
Path to the JSON configuration file |
BACKUP_PERIOD |
0 |
Set to a period (i.e. 72h15m) to enable zip backups of data/config.json and data/updates.json in a zip file |
BACKUP_DIRECTORY |
/updater/data |
Directory to write backup zip files to if BACKUP_PERIOD is not 0. |
RESOLVER_ADDRESS |
Your network DNS | A plaintext DNS address to use to resolve your domain names defined in your settings only. For example it can be 1.1.1.1:53. This is useful for split dns, see #389 |
LOG_LEVEL |
info |
Level of logging, debug, info, warning or error |
LOG_CALLER |
hidden |
Show caller per log line, |
$ claude mcp add ddns-updater \
-- python -m otcore.mcp_server <graph>