Using Podman Quadlets for Dynamic DNS with desec.io

rwxd April 26, 2025 #podman #systemd #rootless #quadlets #dyndns #desec.io #ddns-updater

Dynamic DNS (DDNS) automatically updates DNS records when your IP address changes. This following post shows how to set up DDNS using ddns-updater, desec.io, and Podman Quadlets.

The podman container can run under the root user or rootless.

DynDNS Architecture

Setup

1. Create Kubernetes Pod YAML

Create a yaml file to store the following manifest:

---
apiVersion: v1
kind: Pod
metadata:
  labels:
    app: ddns-updater
    io.containers.autoupdate: registry
  name: ddns-updater
spec:
  containers:
    - image: docker.io/qmcgaw/ddns-updater:latest
      name: v4
      env:
      - name: LOG_LEVEL
        value: INFO
      - name: SERVER_ENABLED
        value: "false"
      - name: PERIOD
        value: 5m
      - name: CONFIG
        value: >
          {
            "settings": [
              {
                "provider": "desec",
                "domain": "ddns.example.com",
                "token": "your_desec_token_here",
                "ip_version": "ipv4"
              }
            ]
          }

    - image: docker.io/qmcgaw/ddns-updater:latest
      name: v6
      env:
      - name: LOG_LEVEL
        value: INFO
      - name: SERVER_ENABLED
        value: "false"
      - name: HEALTH_SERVER_ADDRESS
        value: "127.0.0.1:9998"
      - name: PERIOD
        value: 5m
      - name: CONFIG
        value: >
          {
            "settings": [
              {
                "provider": "desec",
                "domain": "ddns.example.com",
                "ipv6_suffix": ""
                "token": "your_desec_token_here",
                "ip_version": "ipv6"
              }
            ]
          }

2. Create Podman Quadlet

Create /etc/containers/systemd/ddns-updater.kube (rootfull) or ~/.config/containers/systemd/ddns-updater.kube (rootless):

[Install]
WantedBy=default.target

[Unit]
Description=Dynamic DNS Updater for desec.io
After=network-online.target
Wants=network-online.target

[Kube]
Yaml=<full path to pod yaml>
Network=host

[Service]
Restart=always
RestartSec=10
TimeoutStartSec=900

3. Enable and Start

# rootfull
sudo systemctl daemon-reload
sudo systemctl enable --now ddns-updater

# rootless
systemctl --user daemon-reload
systemctl --user enable --now ddns-updater

Monitoring

Check status:

# rootfull
systemctl status ddns-updater

# rootless
systemctl --user status ddns-updater

View logs:

podman logs ddns-updater-v4
podman logs ddns-updater-v6

# rootfull
journalctl -u ddns-updater

# rootless
journalctl --user -u ddns-updater

Test DNS resolution:

dig +short A ddns.example.com
dig +short AAAA ddns.example.com