# qdm12/ddns-updater architecture

> Architecture diagram of the GitHub repository qdm12/ddns-updater, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-28). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/qdm12/ddns-updater
- Repository: https://github.com/qdm12/ddns-updater

## Overview

DDNS Updater periodically discovers the host’s public IPv4/IPv6 addresses and updates configured DNS records across many providers. The principal workflow starts with configuration and provider settings, then fetches addresses, decides which records need changes, updates DNS, and persists status/history. The application also exposes a web UI and health endpoints, creates periodic data backups, and supports notifications and healthcheck reporting. The main entry point shows how services are assembled; unsampled provider implementations are represented by their existing directory.

Main entry points: [`cmd/ddns-updater/main.go`](https://github.com/qdm12/ddns-updater/blob/master/cmd/ddns-updater/main.go) (Application startup), [`internal/update/service.go`](https://github.com/qdm12/ddns-updater/blob/master/internal/update/service.go) (Update scheduler), [`internal/data/data.go`](https://github.com/qdm12/ddns-updater/blob/master/internal/data/data.go) (Record database interface), [`pkg/publicip/publicip.go`](https://github.com/qdm12/ddns-updater/blob/master/pkg/publicip/publicip.go) (Public IP discovery)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_setup["Startup and configuration"]
  node_main["Application startup<br/>[main.go]"]
  node_config["Runtime settings<br/>[settings.go]"]
  node_params["Provider settings reader<br/>[reader.go]"]
end

subgraph group_update["Address and DNS updates"]
  node_provider_registry["DNS provider adapters"]
  node_update_service["Update scheduler<br/>[service.go]"]
  node_update_logic["Record update logic<br/>[update.go]"]
  node_publicip["Public IP discovery<br/>[publicip.go]"]
  node_http_ip["HTTP IP sources"]
  node_dns_ip["DNS IP sources"]
  node_resolver["DNS record resolver<br/>[resolver.go]"]
end

subgraph group_state["Records and persistence"]
  node_records["Record and history model<br/>[records.go]"]
  node_data["Record database interface<br/>[data.go]"]
  node_json_db[("JSON history store<br/>[database.go]")]
end

subgraph group_interfaces["Web and health"]
  node_web_server["Web UI server<br/>[server.go]"]
  node_web_handler["UI and update handlers<br/>[handler.go]"]
  node_health_server["Health server<br/>[server.go]"]
  node_health_check["DNS health checks<br/>[check.go]"]
end

subgraph group_operations["Operations"]
  node_backup["Data backups<br/>[service.go]"]
  node_backup_zip["Backup archive writer<br/>[zip.go]"]
  node_notifications["Notifications<br/>[shoutrrr.go]"]
  node_healthchecks["Healthcheck reporting<br/>[healthchecksio.go]"]
end

node_user(("Operator"))
node_ip_service["Public IP services"]
node_dns_service["Authoritative DNS providers"]
node_notification_service["Notification service"]
node_healthchecks_service["Healthcheck service"]
node_web_client(("Web UI user"))

node_user -->|"starts"| node_main
node_main -->|"loads settings"| node_config
node_main -->|"reads providers"| node_params
node_main -->|"starts scheduler"| node_update_service
node_main -->|"starts server"| node_web_server
node_main -->|"starts health"| node_health_server
node_main -->|"starts backups"| node_backup
node_main -->|"sends notices"| node_notifications
node_params -->|"builds providers"| node_provider_registry
node_update_service -->|"fetches addresses"| node_publicip
node_publicip -->|"queries sources"| node_http_ip
node_publicip -->|"queries sources"| node_dns_ip
node_http_ip -->|"requests address"| node_ip_service
node_dns_ip -->|"queries address"| node_ip_service
node_update_service -->|"checks DNS records"| node_resolver
node_resolver -->|"resolves domain"| node_dns_service
node_update_service -->|"updates records"| node_update_logic
node_update_logic -->|"dispatches update"| node_provider_registry
node_provider_registry -->|"changes DNS"| node_dns_service
node_update_service -->|"reads and updates"| node_data
node_data -->|"persists history"| node_json_db
node_main -->|"loads record history"| node_records
node_web_client -->|"uses UI"| node_web_server
node_web_server -->|"dispatches requests"| node_web_handler
node_web_handler -->|"reads records"| node_data
node_web_handler -->|"forces update"| node_update_service
node_health_server -->|"runs checks"| node_health_check
node_health_check -->|"checks record state"| node_data
node_health_check -->|"resolves domains"| node_resolver
node_backup -->|"writes archives"| node_backup_zip
node_backup_zip -->|"backs up data"| node_json_db
node_notifications -.->|"sends messages"| node_notification_service
node_update_service -->|"reports update state"| node_healthchecks
node_healthchecks -.->|"pings service"| node_healthchecks_service

click node_main "https://github.com/qdm12/ddns-updater/blob/master/cmd/ddns-updater/main.go"
click node_config "https://github.com/qdm12/ddns-updater/blob/master/internal/config/settings.go"
click node_params "https://github.com/qdm12/ddns-updater/blob/master/internal/params/reader.go"
click node_provider_registry "https://github.com/qdm12/ddns-updater/tree/master/internal/provider/providers"
click node_update_service "https://github.com/qdm12/ddns-updater/blob/master/internal/update/service.go"
click node_update_logic "https://github.com/qdm12/ddns-updater/blob/master/internal/update/update.go"
click node_publicip "https://github.com/qdm12/ddns-updater/blob/master/pkg/publicip/publicip.go"
click node_http_ip "https://github.com/qdm12/ddns-updater/tree/master/pkg/publicip/http"
click node_dns_ip "https://github.com/qdm12/ddns-updater/tree/master/pkg/publicip/dns"
click node_resolver "https://github.com/qdm12/ddns-updater/blob/master/internal/resolver/resolver.go"
click node_records "https://github.com/qdm12/ddns-updater/blob/master/internal/records/records.go"
click node_data "https://github.com/qdm12/ddns-updater/blob/master/internal/data/data.go"
click node_json_db "https://github.com/qdm12/ddns-updater/blob/master/internal/persistence/json/database.go"
click node_web_server "https://github.com/qdm12/ddns-updater/blob/master/internal/server/server.go"
click node_web_handler "https://github.com/qdm12/ddns-updater/blob/master/internal/server/handler.go"
click node_health_server "https://github.com/qdm12/ddns-updater/blob/master/internal/health/server.go"
click node_health_check "https://github.com/qdm12/ddns-updater/blob/master/internal/health/check.go"
click node_backup "https://github.com/qdm12/ddns-updater/blob/master/internal/backup/service.go"
click node_backup_zip "https://github.com/qdm12/ddns-updater/blob/master/internal/backup/zip.go"
click node_notifications "https://github.com/qdm12/ddns-updater/blob/master/internal/shoutrrr/shoutrrr.go"
click node_healthchecks "https://github.com/qdm12/ddns-updater/blob/master/internal/healthchecksio/healthchecksio.go"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_main,node_config,node_params,node_web_client toneBlue
class node_provider_registry,node_update_service,node_update_logic,node_publicip,node_http_ip,node_dns_ip,node_resolver toneAmber
class node_records,node_data,node_json_db toneMint
class node_web_server,node_web_handler,node_health_server,node_health_check toneRose
class node_backup,node_backup_zip,node_notifications,node_healthchecks,node_user,node_ip_service,node_dns_service,node_notification_service,node_healthchecks_service toneIndigo
```

## Components

### Startup and configuration

- [Application startup](https://github.com/qdm12/ddns-updater/blob/master/cmd/ddns-updater/main.go): `cmd/ddns-updater/main.go`
- [Runtime settings](https://github.com/qdm12/ddns-updater/blob/master/internal/config/settings.go): `internal/config/settings.go`
- [Provider settings reader](https://github.com/qdm12/ddns-updater/blob/master/internal/params/reader.go): `internal/params/reader.go`

### Address and DNS updates

- [DNS provider adapters](https://github.com/qdm12/ddns-updater/tree/master/internal/provider/providers): `internal/provider/providers`
- [Update scheduler](https://github.com/qdm12/ddns-updater/blob/master/internal/update/service.go): `internal/update/service.go`
- [Record update logic](https://github.com/qdm12/ddns-updater/blob/master/internal/update/update.go): `internal/update/update.go`
- [Public IP discovery](https://github.com/qdm12/ddns-updater/blob/master/pkg/publicip/publicip.go): `pkg/publicip/publicip.go`
- [HTTP IP sources](https://github.com/qdm12/ddns-updater/tree/master/pkg/publicip/http): `pkg/publicip/http`
- [DNS IP sources](https://github.com/qdm12/ddns-updater/tree/master/pkg/publicip/dns): `pkg/publicip/dns`
- [DNS record resolver](https://github.com/qdm12/ddns-updater/blob/master/internal/resolver/resolver.go): `internal/resolver/resolver.go`

### Records and persistence

- [Record and history model](https://github.com/qdm12/ddns-updater/blob/master/internal/records/records.go): `internal/records/records.go`
- [Record database interface](https://github.com/qdm12/ddns-updater/blob/master/internal/data/data.go): `internal/data/data.go`
- [JSON history store](https://github.com/qdm12/ddns-updater/blob/master/internal/persistence/json/database.go): `internal/persistence/json/database.go`

### Web and health

- [Web UI server](https://github.com/qdm12/ddns-updater/blob/master/internal/server/server.go): `internal/server/server.go`
- [UI and update handlers](https://github.com/qdm12/ddns-updater/blob/master/internal/server/handler.go): `internal/server/handler.go`
- [Health server](https://github.com/qdm12/ddns-updater/blob/master/internal/health/server.go): `internal/health/server.go`
- [DNS health checks](https://github.com/qdm12/ddns-updater/blob/master/internal/health/check.go): `internal/health/check.go`

### Operations

- [Data backups](https://github.com/qdm12/ddns-updater/blob/master/internal/backup/service.go): `internal/backup/service.go`
- [Backup archive writer](https://github.com/qdm12/ddns-updater/blob/master/internal/backup/zip.go): `internal/backup/zip.go`
- [Notifications](https://github.com/qdm12/ddns-updater/blob/master/internal/shoutrrr/shoutrrr.go): `internal/shoutrrr/shoutrrr.go`
- [Healthcheck reporting](https://github.com/qdm12/ddns-updater/blob/master/internal/healthchecksio/healthchecksio.go): `internal/healthchecksio/healthchecksio.go`

### Other components

- **Operator**
- **Public IP services**
- **Authoritative DNS providers**
- **Notification service**
- **Healthcheck service**
- **Web UI user**

## Connections

- Operator → Application startup: starts
- Application startup → Runtime settings: loads settings
- Application startup → Provider settings reader: reads providers
- Application startup → Update scheduler: starts scheduler
- Application startup → Web UI server: starts server
- Application startup → Health server: starts health
- Application startup → Data backups: starts backups
- Application startup → Notifications: sends notices
- Provider settings reader → DNS provider adapters: builds providers
- Update scheduler → Public IP discovery: fetches addresses
- Public IP discovery → HTTP IP sources: queries sources
- Public IP discovery → DNS IP sources: queries sources
- HTTP IP sources → Public IP services: requests address
- DNS IP sources → Public IP services: queries address
- Update scheduler → DNS record resolver: checks DNS records
- DNS record resolver → Authoritative DNS providers: resolves domain
- Update scheduler → Record update logic: updates records
- Record update logic → DNS provider adapters: dispatches update
- DNS provider adapters → Authoritative DNS providers: changes DNS
- Update scheduler → Record database interface: reads and updates
- Record database interface → JSON history store: persists history
- Application startup → Record and history model: loads record history
- Web UI user → Web UI server: uses UI
- Web UI server → UI and update handlers: dispatches requests
- UI and update handlers → Record database interface: reads records
- UI and update handlers → Update scheduler: forces update
- Health server → DNS health checks: runs checks
- DNS health checks → Record database interface: checks record state
- DNS health checks → DNS record resolver: resolves domains
- Data backups → Backup archive writer: writes archives
- Backup archive writer → JSON history store: backs up data
- Notifications → Notification service: sends messages
- Update scheduler → Healthcheck reporting: reports update state
- Healthcheck reporting → Healthcheck service: pings service
