ddns-updater

ddns-updater

Aplicación Docker from Diamond Precision Computing's Repository

Visión general

Lightweight universal DDNS Updater with Docker and web UI

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

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

  • 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 mkdir /mnt/user/appdata/ddns-updater
    touch /mnt/user/appdata/ddns-updater/config.json
    # Owned by user ID of Docker container (1000)
    chown -R 1000 /mnt/user/appdata/ddns-updater
    # all access (for creating json database file data/updates.json)
    chmod 700 /mnt/user/appdata/ddns-updater
    # read access only
    chmod 400 /mnt/user/appdata/ddns-updater/config.json
    

    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.

  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.

GHCR

Images are also added to the Github Container Registry. To use the GHCR container replace qmcgaw/ddns-updater to ghcr.io/qdm12/ddns-updater, further details are available here

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. RESOLVER_ADDRESS Your network DNS A plaintext DNS address to use, such as 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) 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:

  • PUBLICIP_HTTP_PROVIDERS gets your public IPv4 or IPv6 address. It can be one or more of the following:
  • PUBLICIPV4_HTTP_PROVIDERS gets your public IPv4 address only. It can be one or more of the following:
  • PUBLICIPV6_HTTP_PROVIDERS gets your public IPv6 address only. It can be one or more of the following:
  • 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
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 CREATED 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


Many thanks to J. Famiglietti for supporting me financially

Argumentos en tiempo de ejecución

Interfaz web
http://[IP]:[PORT:8000]
Red
bridge
Concha
sh
Privilegiado
false

Configuración de plantillas

WebUIPorttcp

Container Port: 8000

Objetivo
8000
Por defecto
8000
ConfigPathrw

Container Path: /updater/data

Objetivo
/updater/data
Por defecto
/mnt/user/appdata/ddns-updater
Valor
/mnt/user/appdata/ddns-updater
TZVariable

Timezone to have accurate times, i.e. America/Montreal

PUBLICIP_FETCHERSVariable

Comma separated fetcher types to obtain the public IP address from http and dns

Por defecto
all|http|dns
Valor
all
PUBLICIP_HTTP_PROVIDERSVariable

PUBLICIP_HTTP_PROVIDERS gets your public IPv4 or IPv6 address. It can be one or more of the following: (default:all), opendns, ifconfig, ipinfo, ddns, google. You can also specify an HTTPS URL such as https://ipinfo.io/ip

Por defecto
all
Valor
all
PUBLICIPV4_HTTP_PROVIDERSVariable

PUBLICIPV4_HTTP_PROVIDERS gets your public IPv4 address only. It can be one or more of the following: (default:all), ipify, noip. You can also specify an HTTPS URL such as https://ipinfo.io/ip

Por defecto
all
Valor
all
PUBLICIPV6_HTTP_PROVIDERSVariable

PUBLICIPV6_HTTP_PROVIDERS gets your public IPv6 address only. It can be one or more of the following: (default:all), ipify, noip. You can also specify an HTTPS URL such as https://ipinfo.io/ip

Por defecto
all
Valor
all
PUBLICIP_DNS_PROVIDERSVariable

PUBLICIP_DNS_PROVIDERS gets your public IPv4 address only or IPv6 address only or one of them. It can be one or more of the following: (default:all), google, cloudflare,

Por defecto
all
Valor
all
PUBLICIP_DNS_TIMEOUTVariable

Public IP DNS query timeout (in seconds)

Por defecto
3s
Valor
3s
UPDATE_COOLDOWN_PERIODVariable

Duration to cooldown between updates for each record. This is useful to avoid being rate limited or banned. (in minutes)

Por defecto
5m
Valor
5m
HTTP_TIMEOUTVariable

Timeout for all HTTP requests (in seconds)

Por defecto
10s
Valor
10s
BACKUP_DIRECTORYVariable

Directory to read and write data files from internally

Por defecto
/updater/data/backup
Valor
/updater/data/backup
BACKUP_PERIODVariable

Set to a period (i.e. 72h15m) to enable zip backups of data/config.json and data/updates.json in a zip file

Por defecto
0
Valor
0
LOG_LEVELVariable

Level of logging, debug, info, warning or error

Por defecto
info|warning|error|debug
Valor
info
LOG_CALLERVariable

Container Variable: LOG_CALLER

Por defecto
hidden|short
Valor
hidden
ROOT_URLVariable

URL path to append to all paths to the webUI (i.e. /ddns for accessing https://example.com/ddns through a proxy)

Por defecto
/
Valor
/
SHOUTRRR_ADDRESSESVariable

(optional) Comma separated list of Shoutrrr addresses (notification services) -- (See GitHub Documentation)

HEALTH_SERVER_ADDRESSVariable

Health server listening address

Por defecto
127.0.0.1:9999
Valor
127.0.0.1:9999

Descargar estadísticas

16,274,209
Descargas totales
537,724
Este mes
365,331
Media / Mes

Descargas totales a lo largo del tiempo

Cargando gráfico...

Detalles

Repositorio
qmcgaw/ddns-updater
Última actualización2026-05-01
Visto por primera vez2021-08-06

Ejecute ddns-updater en Unraid.

ddns-updater se encuentra en Community Apps para Unraid OS. Explore Unraid para crear un servidor doméstico flexible, un NAS o un laboratorio doméstico.