Deploy ddns-updater on Kubernetes. Keeps DNS A/AAAA records
updated across 50+ providers (Cloudflare, Route53, DuckDNS, Namecheap, GoDaddy, Hetzner, and more) with
a responsive web dashboard and persistent update history.
config.settings embeds credentials in Helm values — prefer existingSecret
Inline config.settings entries (with token, password, or API keys) are stored in a Kubernetes Secret created by
the chart. However, they are visible in Helm release history via helm get values. For production, pre-create a
Secret containing a config.json file and reference it with config.existingSecret.
Key Features
50+ DNS providers — Cloudflare, Route53, DuckDNS, Namecheap, GoDaddy, Hetzner, and more
Web UI — responsive dashboard at port 8000 for monitoring update status and history
Multi-record support — manage records from different providers in a single deployment
Persistent history — updates.json stored in a PVC survives pod restarts
existingSecret — bring your own config.json Secret for GitOps and production use
Configurable IP detection — HTTP, DNS, or combined public IP fetching strategies
The chart runs one DDNS writer with a Recreate deployment strategy. It reads
config.json from a chart-managed or existing Secret, polls public IP sources,
updates provider APIs, stores update history on the PVC, and serves the status
UI through a ClusterIP Service by default. service.type can select NodePort or
LoadBalancer instead. Horizontal replicas are intentionally avoided because
concurrent writers can race DNS updates and history writes.
# values.yaml — Web UI exposed via Ingress with TLS# The web UI runs on port 8000 in the container (mapped to 80 on the Service).config: existingSecret: ddns-config existingSecretKey: config.jsonddns: period: 5m rootUrl: / # set to '/ddns' if behind a reverse proxy on a subpathpersistence: enabled: true size: 256Miingress: enabled: true ingressClassName: traefik annotations: cert-manager.io/cluster-issuer: letsencrypt-prod hosts: - host: ddns.example.com paths: - path: / pathType: Prefix tls: - secretName: ddns-tls hosts: - ddns.example.com
Configuration Reference
Core
Parameter
Type
Default
Description
nameOverride
string
""
Override the chart name.
fullnameOverride
string
""
Override the full release name.
commonLabels
object
{}
Extra labels added to all resources.
Image
Parameter
Type
Default
Description
image.repository
string
docker.io/qmcgaw/ddns-updater
DDNS Updater container image.
image.tag
string
"2.10.0"
Image tag.
image.pullPolicy
string
IfNotPresent
Image pull policy.
imagePullSecrets
array
[]
Pull secrets for private registries.
DDNS Configuration
Parameter
Type
Default
Description
config.settings
array
[]
Inline DNS records to update. Each entry requires provider-specific fields.
config.existingSecret
string
""
Existing Secret containing a config.json file.
config.existingSecretKey
string
config.json
Key inside the existing secret for the config file.
config.json is JSON, not YAML
The config.existingSecret must contain a JSON file. The config.settings entries in values.yaml are YAML but are
converted to JSON by the chart when creating the internal Secret. When using existingSecret, create a valid JSON
file following the ddns-updater settings
format.
Application Options
Parameter
Type
Default
Description
ddns.period
string
5m
Interval between IP checks and DNS updates.
ddns.httpTimeout
string
10s
HTTP timeout for IP detection and DNS provider API calls.
ddns.publicIpFetchers
string
all
Public IP detection method: all, http, or dns.
ddns.updateCooldownPeriod
string
5m
Minimum time between updates per record. Prevents flapping on rapid IP change.
ddns.logLevel
string
info
Log verbosity: debug, info, warning, or error.
ddns.port
integer
8000
Web UI container listen port.
ddns.rootUrl
string
/
Root URL path for the web UI. Change when hosting behind a reverse proxy at a subpath.
ddns.extraEnv
array
[]
Extra environment variables for the container.
Persistence
Parameter
Type
Default
Description
persistence.enabled
boolean
true
Enable PVC for updates.json (update history and status).
persistence.size
string
256Mi
PVC size. Tiny — update history is a small JSON file.
persistence.storageClass
string
""
StorageClass for the PVC.
persistence.accessModes
array
[ReadWriteOnce]
PVC access modes.
persistence.existingClaim
string
""
Use an existing PVC.
Service
Parameter
Type
Default
Description
service.type
string
ClusterIP
Kubernetes service type.
service.port
integer
80
Service port (maps to container 8000).
service.annotations
object
{}
Annotations for the Service.
Ingress
Parameter
Type
Default
Description
ingress.enabled
boolean
false
Enable an Ingress resource for the web UI.
ingress.ingressClassName
string
traefik
Ingress class name.
ingress.annotations
object
{}
Annotations for the Ingress (e.g. cert-manager).
ingress.hosts
array
[]
Ingress host and path rules.
ingress.tls
array
[]
TLS configuration.
Probes
Parameter
Type
Default
Description
probes.startup.enabled
boolean
true
Enable startup probe.
probes.startup.initialDelaySeconds
integer
5
Startup probe initial delay.
probes.startup.periodSeconds
integer
5
Startup probe period.
probes.startup.failureThreshold
integer
12
Startup probe failure threshold.
probes.liveness.enabled
boolean
true
Enable liveness probe.
probes.liveness.periodSeconds
integer
15
Liveness probe period.
probes.liveness.failureThreshold
integer
3
Liveness probe failure threshold.
probes.readiness.enabled
boolean
true
Enable readiness probe.
probes.readiness.periodSeconds
integer
10
Readiness probe period.
probes.readiness.failureThreshold
integer
3
Readiness probe failure threshold.
Resources and Security
Parameter
Type
Default
Description
resources.requests.cpu
string
10m
Default CPU request.
resources.requests.memory
string
32Mi
Default memory request.
resources.limits.cpu
string
100m
Default CPU limit.
resources.limits.memory
string
128Mi
Default memory limit.
podSecurityContext
object
non-root seccomp defaults
Pod-level security context.
securityContext
object
non-root read-only defaults
Container-level security context.
Service Account
Parameter
Type
Default
Description
serviceAccount.create
boolean
false
Create a dedicated ServiceAccount.
serviceAccount.automountServiceAccountToken
boolean
false
Mount Kubernetes API token into pods.
serviceAccount.name
string
""
Override the ServiceAccount name.
serviceAccount.annotations
object
{}
Annotations for the ServiceAccount.
Scheduling
Parameter
Type
Default
Description
nodeSelector
object
{}
Node selector for scheduling.
tolerations
array
[]
Tolerations for scheduling.
affinity
object
{}
Affinity rules.
topologySpreadConstraints
array
[]
Topology spread constraints.
priorityClassName
string
""
PriorityClass for the pod.
terminationGracePeriodSeconds
integer
30
Termination grace period.
podLabels
object
{}
Extra labels for the pod.
podAnnotations
object
{}
Extra annotations for the pod.
Extra
Parameter
Type
Default
Description
extraVolumes
array
[]
Extra volumes to attach to the pod.
extraVolumeMounts
array
[]
Extra volume mounts for the container.
extraManifests
array
[]
Extra Kubernetes manifests deployed alongside the chart.
Upgrade Safety
Keep the release name, nameOverride, fullnameOverride, configuration Secret
reference, and persistence.existingClaim stable so upgrades retain workload,
Service, and PVC identity. Export the stored overrides, review them against the
new schema, and use a complete values file with the normal Helm merge:
The file must retain every non-default setting, especially
config.existingSecret or config.settings; omitting both can replace the
active configuration with an empty chart-managed Secret. --reuse-values
preserves stored overrides but also preserves old defaults, so compare the
stored values with the new schema before using it. Back up config.json and
update history, then confirm both the UI and a real provider update after the
pod becomes Ready.
Troubleshooting
For startup failures, validate config.json and existingSecretKey.
For stale records, inspect provider errors in the logs and verify outbound
DNS, public IP checker, and provider API connectivity.
For an unavailable proxied UI, align ddns.rootUrl, the Service port, and the
Ingress path.
For PVC mount failures, verify the existing claim, access mode, and
StorageClass before changing persistence settings.