Need help with ddns-updater?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

qdm12
351 Stars 42 Forks MIT License 404 Commits 36 Opened issues

Description

Container to update DNS records periodically with WebUI for many DNS providers

Services available

!
?

Need anything else?

Contributors list

# 47,709
Go
Docker
golang
godaddy
371 commits
# 115,885
Node.js
PHP
pageobj...
dyndns
11 commits
# 214,048
golang
C
OpenCV
mjpeg
3 commits
# 245,884
slack
web-int...
golang
dyndns
2 commits
# 481,113
PHP
Shell
dyndns
godaddy
1 commit
# 456,043
Rails
Shell
HTML
dyndns
1 commit
# 3,030
Python
pinboar...
web-arc...
chromiu...
1 commit
# 37,078
Lua
api-gat...
luajit
Perl
1 commit
# 468,709
HTML
angular...
angular...
dyndns
1 commit
# 288,433
parser-...
node
HTML
godaddy
1 commit

Lightweight universal DDNS Updater with Docker and web UI

Light container updating DNS A and/or AAAA records periodically for multiple DNS providers

DDNS Updater logo

Build status

dockeri.co

Last release Last Docker tag Last release size GitHub last release date Commits since release

Latest size

GitHub last commit GitHub commit activity GitHub closed PRs GitHub issues GitHub closed issues

Lines of code Code size GitHub repo size Go version

MIT Visitors count

Features

  • Updates periodically A records for different DNS providers:
    • Aliyun
    • Cloudflare
    • DD24
    • DDNSS.de
    • DigitalOcean
    • DonDominio
    • DNSOMatic
    • DNSPod
    • Dreamhost
    • DuckDNS
    • DynDNS
    • FreeDNS
    • Gandi
    • GoDaddy
    • Google
    • He.net
    • Infomaniak
    • Linode
    • LuaDNS
    • Namecheap
    • NoIP
    • Njalla
    • OpenDNS
    • OVH
    • Porkbun
    • Selfhost.de
    • Servercow.de
    • Spdyn
    • Strato.de
    • Variomedia.de
    • Want more? Create an issue for it!
  • Web User interface

Web UI

  • 11MB Docker image based on a Go static binary in a Scratch Docker image
  • Persistence with a JSON file updates.json to store old IP addresses with change times for each record
  • Docker healthcheck verifying the DNS resolution of your domains
  • Highly configurable
  • Send notifications with Shoutrrr using
    SHOUTRRR_ADDRESSES
  • Compatible with
    amd64
    ,
    386
    ,
    arm64
    ,
    armv7
    ,
    armv6
    ,
    s390x
    ,
    ppc64le
    ,
    riscv64
    CPU architectures.

Setup

The program reads the configuration from a JSON object, either from a file or from an environment variable.

  1. Create a directory of your choice, say data with a file named config.json inside:

    mkdir data
    touch data/config.json
    # Owned by user ID of Docker container (1000)
    chown -R 1000 data
    # all access (for creating json database file data/updates.json)
    chmod 700 data
    # read access only
    chmod 400 data/config.json
    

    If you want to use another user ID, build the image yourself with

    --build-arg UID=
    . You could also just run the container as root with
    --user="0"
    but this is not advised security wise.
  2. Write a JSON configuration in data/config.json, for example:

    {
        "settings": [
            {
                "provider": "namecheap",
                "domain": "example.com",
                "host": "@",
                "password": "e5322165c1d74692bfa6d807100c0310"
            }
        ]
    }
    

    You can find more information in the configuration section to customize it.

  3. Run the container with

    docker run -d -p 8000:8000/tcp -v "$(pwd)"/data:/updater/data qmcgaw/ddns-updater
    
  4. ⚠️ If you use IPv6, you might need to set

    -e IPV6_PREFIX=/64
    (
    /64
    is your prefix, depending on your ISP)
  5. (Optional) You can also set your JSON configuration as a single environment variable line (i.e.

    {"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.

Next steps

You can also use docker-compose.yml with:

docker-compose up -d

You can update the image with

docker pull qmcgaw/ddns-updater
. Other Docker image tags are available.

Configuration

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:

  • you can specify multiple hosts for the same domain using a comma separated list. For example with
    "host": "@,subdomain1,subdomain2",
    .

Environment variables

| Environment variable | Default | Description | | --- | --- | --- | |

CONFIG
| | One line JSON object containing the entire config (takes precendence over config.json file) if specified | |
PERIOD
|
5m
| Default period of IP address check, following this format | |
IPV6_PREFIX
|
/128
| IPv6 prefix used to mask your public IPv6 address and your record IPv6 address. Ranges from
/0
to
/128
depending on your ISP. | |
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 | |
LISTENING_PORT
|
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 | |
DATADIR
|
/updater/data
| Directory to read and write data files from internally | |
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
. | |
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) | |
TZ
| | Timezone to have accurate times, i.e.
America/Montreal
|

Public IP

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:

Host firewall

If you have a host firewall in place, this container needs the following ports:

  • TCP 443 outbound for outbound HTTPS
  • UDP 53 outbound for outbound DNS resolution
  • TCP 8000 inbound (or other) for the WebUI

Architecture

At program start and every period (5 minutes by default):

  1. Fetch your public IP address
  2. For each record:
    1. DNS resolve it to obtain its current IP address(es)
      • If the resolution fails, update the record with your public IP address by calling the DNS provider API and finish
    2. Check if your public IP address is within the resolved IP addresses
      • Yes: skip the update
      • No: update the record with your public IP address by calling the DNS provider API

💡 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.

Special case: Cloudflare

For Cloudflare records with the

proxied
option, the following is done.

At program start and every period (5 minutes by default), for each record:

  1. Fetch your public IP address
  2. For each record:
    1. Check the last IP address (persisted in
      updates.json
      ) for that record
      • If it doesn't exist, update the record with your public IP address by calling the DNS provider API and finish
    2. Check if your public IP address matches the last IP address you updated the record with
      • Yes: skip the update
      • No: update the record with your public IP address by calling the DNS provider API

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.

Testing

  • The automated healthcheck verifies all your records are up to date using DNS lookups
  • You can also manually check, by:
    1. Going to your DNS management webpage
    2. Setting your record to
      127.0.0.1
    3. Run the container
    4. Refresh the DNS management webpage and verify the update happened

Build the image

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 | |
BUILD_DATE
|
an unknown date
| Build date of the program and Docker image | |
COMMIT
|
unknown
| Commit hash of the program and Docker image |

Development and contributing

License

This repository is under an MIT license

Used in external projects

Support

Sponsor me on Github or donate to paypal.me/qmcgaw

https://github.com/sponsors/qdm12 https://www.paypal.me/qmcgaw

Many thanks to J. Famiglietti for supporting me financially 🥇👍

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.