Container to update DNS records periodically with WebUI for many DNS providers
MIT License
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/ |
Available as a Docker image qmcgaw/ddns-updater
and ghcr.io/qdm12/ddns-updater
Available as zero-dependency binaries for Linux, Windows and MacOS
🆕 Available in the AUR as ddns-updater
- see #808
Updates periodically A records for different DNS providers:
Web user interface (Desktop)
Web user interface (Mobile)
Send notifications with Shoutrrr using SHOUTRRR_ADDRESSES
Container (Docker/K8s) specific features:
amd64
, 386
, arm64
, armv7
, armv6
, s390x
, ppc64le
, riscv64
CPU architecturesPersistence with a JSON file updates.json to store old IP addresses with change times for each record
Download the pre-built program for your platform from the assets of a release in the releases page. You can alternatively download, build and install the latest version of the program by installing Go and then run go install github.com/qdm12/ddns-updater/cmd/ddns-updater@latest
.
For Linux and MacOS, make the program executable with chmod +x ddns-updater
.
In the directory where the program is saved, create a directory data
.
Write a JSON configuration in data/config.json
, for example:
{
"settings": [
{
"provider": "namecheap",
"domain": "sub.example.com",
"password": "e5322165c1d74692bfa6d807100c0310"
}
]
}
You can find more information in the configuration section to customize it.
Run the program with ./ddns-updater
(./ddns-updater.exe
on Windows) or by double-clicking on it.
The following is optional.
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 containermkdir 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:
1000
touch data/config.json
chmod u+r data/config.json
Edit data/config.json, for example:
{
"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
docker run -d -p 8000:8000/tcp -v "$(pwd)"/data:/updater/data qmcgaw/ddns-updater
The following is optional.
docker-compose up -d
docker pull qmcgaw/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",
.🆕 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, hidden or short
|
SHOUTRRR_ADDRESSES |
(optional) Comma separated list of Shoutrrr addresses (notification services) | |
SHOUTRRR_DEFAULT_TITLE |
DDNS Updater |
Default title for Shoutrrr notifications |
TZ |
Timezone to have accurate times, i.e. America/Montreal
|
|
UMASK |
System current umask | Umask to set for the program in octal, i.e. 0022
|
By default, all public IP fetching types are used and cycled (over DNS and over HTTPs).
On top of that, for each fetching method, all echo services available are cycled on each request.
This allows you not to be blocked for making too many requests.
You can otherwise customize it with the following:
PUBLICIP_HTTP_PROVIDERS
gets your public IPv4 or IPv6 address. It can be one or more of the following:
ipify
using https://api64.ipify.org
ifconfig
using https://ifconfig.io/ip
ipinfo
using https://ipinfo.io/ip
spdyn
using https://checkip.spdyn.de
ipleak
using https://ipleak.net/json
icanhazip
using https://icanhazip.com
ident
using https://ident.me
nnev
using https://ip.nnev.de
wtfismyip
using https://wtfismyip.com/text
seeip
using https://api.seeip.org
changeip
using https://ip.changeip.com
url:
for example url:https://ipinfo.io/ip
PUBLICIPV4_HTTP_PROVIDERS
gets your public IPv4 address only. It can be one or more of the following:
ipleak
using https://ipv4.ipleak.net/json
ipify
using https://api.ipify.org
icanhazip
using https://ipv4.icanhazip.com
ident
using https://v4.ident.me
nnev
using https://ip4.nnev.de
wtfismyip
using https://ipv4.wtfismyip.com/text
seeip
using https://ipv4.seeip.org
url:
for example url:https://ipinfo.io/ip
PUBLICIPV6_HTTP_PROVIDERS
gets your public IPv6 address only. It can be one or more of the following:
ipleak
using https://ipv6.ipleak.net/json
ipify
using https://api6.ipify.org
icanhazip
using https://ipv6.icanhazip.com
ident
using https://v6.ident.me
nnev
using https://ip6.nnev.de
wtfismyip
using https://ipv6.wtfismyip.com/text
seeip
using https://ipv6.seeip.org
url:
for example url:https://ipinfo.io/ip
PUBLICIP_DNS_PROVIDERS
gets your public IPv4 address only or IPv6 address only or one of them (see #136). It can be one or more of the following:
cloudflare
opendns
If you have a host firewall in place, this container needs the following ports:
At program start and every period (5 minutes by default):
💡 We do DNS resolution every period so it detects a change made to the record manually, for example on the DNS provider web UI 💡 As DNS resolutions are essentially free and without rate limiting, these are great to avoid getting banned for too many requests.
For Cloudflare records with the proxied
option, the following is done.
At program start and every period (5 minutes by default), for each record:
updates.json
) for that record
This is the only way as doing a DNS resolution on the record will give the IP address of a Cloudflare server instead of your server.
⚠️ This has the disadvantage that if the record is changed manually, the program will not detect it. We could do an API call to get the record IP address every period, but that would get you banned especially with a low period duration.
127.0.0.1
You can build the image yourself with:
docker build -t qmcgaw/ddns-updater https://github.com/qdm12/ddns-updater.git
You can use optional build arguments with --build-arg KEY=VALUE
from the table below:
Build argument | Default | Description |
---|---|---|
UID |
1000 |
User ID running the container |
GID |
1000 |
User group ID running the container |
VERSION |
unknown |
Version of the program and Docker image |
CREATED |
an unknown date |
Build date of the program and Docker image |
COMMIT |
unknown |
Commit hash of the program and Docker image |
This repository is under an MIT license
Sponsor me on Github or donate to paypal.me/qmcgaw
Many thanks to J. Famiglietti for supporting me financially 🥇👍