Dynamic DNS (System App)
How PodWarden's built-in DDNS system app auto-discovers gateway hosts and keeps DNS records in sync when public IPs change
What you see
URL: /network (DDNS tab)
The Dynamic DNS (DDNS) system app is always installed in PodWarden. It runs entirely server-side — no Kubernetes deployment is required. Every five minutes it checks the public IP of each gateway host and, if the IP has changed, updates DNS records with each configured provider.
DDNS configurations are managed from the Network page on the DDNS tab. A configuration links one gateway host to one DNS provider, and controls which domain names get updated.
How DDNS fits into PodWarden's network model
PodWarden's network model has three layers that work together:
| Layer | Object | Role |
|---|---|---|
| Physical ingress point | Gateway host | The server with the public IP |
| DNS management | Domain + DDNS config | Keeps the A record pointed at the gateway's current IP |
| Traffic routing | Ingress rule | Routes hostnames to services behind the gateway |
The DDNS system app bridges the first two layers: when the gateway's IP changes, DDNS updates the domain's A record so traffic continues to reach the right host.
DDNS provider list
| Provider | Config fields | Notes |
|---|---|---|
| Cloudflare | Zone ID, API token, list of A record names | Recommended. Supports auto-discovery and auto-import of the zone's base domain. Also manages optional CNAME records. |
| DuckDNS | Token, subdomain names (without .duckdns.org) | Free dynamic DNS using DuckDNS update API. |
| Namecheap | Host, domain, dynamic DNS password | Uses Namecheap's dynamicdns.park-your-domain.com endpoint. |
| Google Domains / Squarespace | Hostname, username, password | Uses the dyndns2 protocol via HTTP Basic auth. |
| No-IP | Hostname, username, password | Uses the dyndns2 protocol via HTTP Basic auth. |
| Dynu | Hostname, username, password (hash) | Uses the dyndns2 protocol. Dynu requires the password to be an MD5 or SHA-256 hash. |
| FreeDNS (afraid.org) | Update token | Uses the unique per-host update key from afraid.org. |
| Porkbun | Domain, subdomain, API key, secret API key | Uses Porkbun's REST API. Leave subdomain empty for root domain. |
| DigitalOcean | Domain, record ID, API token | Updates a specific A record by its numeric ID. |
| Custom webhook | URL, HTTP method, body template | Calls any HTTP endpoint. Use {{ip}} in the body template as a placeholder for the detected IP. |
| PodWarden Hub | (none — uses Hub settings) | Reports the new IP to Hub and updates all Hub-managed subdomains automatically. Requires Hub URL and API key to be configured in Settings → Hub. |
DDNS config fields
| Field | Description |
|---|---|
| Name | A label for this configuration (e.g. Cloudflare on gateway-01) |
| Provider | Which DNS service to use (see table above). Cannot be changed after creation. |
| Gateway host | The host whose public IP is tracked. Must have the gateway role. |
| Provider-specific fields | Credentials and record names for the chosen provider |
| Enabled | Toggle to pause updates without deleting the config |
Status badges
| Badge | Meaning |
|---|---|
| Active | Last update succeeded. IP is current. |
| Error | Last update attempt failed. Expand the row to see the error message. |
| Disabled | Config exists but updates are paused. |
| Pending | Config was just created and has not run yet. |
Available actions
| Action | Where | What it does |
|---|---|---|
| Add Provider | Page toolbar | Opens the provider creation form |
| Test (play icon) | Config row | Runs an immediate update regardless of whether the IP has changed. Useful for verifying credentials. |
| Edit (pencil icon) | Config row | Edit the name, gateway host, or provider credentials |
| Enable / Disable (toggle icon) | Config row | Pause or resume updates for this config |
| Delete (trash icon) | Config row | Permanently removes the config (admin only) |
Adding a Cloudflare provider
Cloudflare is the recommended provider because PodWarden can fetch and validate your A records directly from the API.
- Click + Add Provider on the Network DDNS tab.
- Enter a Name (e.g.
example.com on gateway-01). - Select Cloudflare as the provider.
- Enter your Zone ID (found in the Cloudflare dashboard under your domain's overview).
- Enter your API token (needs
Zone:DNS:Editpermission for the target zone). - Enter domains manually, or click the search icon to fetch existing A records from Cloudflare and select them with one click.
- Select the Gateway host whose IP should be tracked.
- Click Add Provider.
After saving, PodWarden automatically imports the zone's base domain into the Domains table and links it to this DDNS config.
Auto-discovery
PodWarden runs an auto-discovery step on every 5-minute check cycle. It looks for gateway hosts that have Cloudflare-managed domains in their ingress rules but no DDNS config, then creates one automatically if a matching Cloudflare API token can be found in an existing config for that zone.
Auto-created configs are named Auto: <domain> on <gateway> and are enabled immediately.
If no existing config with credentials for that zone can be found, auto-discovery skips the gateway and logs a warning. You will also see a "Gateway: Cloudflare domains without DDNS" warning in System Messages.
IP detection strategy
For each gateway host, PodWarden detects the public IP using this priority order:
hosts.public_ip— if a cached public IP is stored for this host- SSH to the gateway and run an IP detection command
- Third-party IP detection services (
ifconfig.me,api.ipify.org,icanhazip.com), with PodWarden Hub's/api/v1/ipendpoint first if Hub is configured
All configs for the same gateway host share a single IP detection call per cycle — PodWarden does not make redundant requests.
Update cycle
The background loop runs every 5 minutes. Within each cycle:
- Auto-discovery runs and creates any missing configs.
- For each enabled config, PodWarden checks whether the gateway's current IP differs from the last recorded IP.
- If the IP has changed, the provider's DNS API is called to update the record.
- If the IP is unchanged, the cycle skips the config with no API call.
The loop starts 30 seconds after PodWarden boots to allow the database connection pool to initialize.
Health monitoring
The DDNS system app registers health checks that run alongside PodWarden's standard 15-minute infrastructure audit:
| Check | Severity | Meaning |
|---|---|---|
| DDNS update failed | Error | A config's last update attempt returned an error. |
| Gateway without DDNS | Warning | A gateway host serves Cloudflare domains via ingress rules but has no DDNS config. |
| DDNS config stale | Warning | An enabled config has not been checked in over 15 minutes — the background loop may not be running. |
These appear on the System Messages page under the DDNS category. Fixing the underlying issue (bad credentials, unreachable gateway, stopped background loop) will auto-resolve the message on the next clean check cycle.
Related docs
- Settings: DDNS — The settings tab that also exposes DDNS configuration
- Zones — Network zones for grouping gateway hosts
- Ingress — Ingress rules that use DDNS-managed domains
- System Messages — DDNS health check alerts