refactor: reduce deployment to one compose file
Container-Image veröffentlichen / container (push) Has been cancelled

This commit is contained in:
admin committed 2026-07-12 22:17:04 +02:00
1 parent 888d9a54a7
commit c8728746f1
12 files changed
+142 -334

No files matched your search

+50 -58
View File
@@ -1,76 +1,68 @@
# Hetzner DynDNS Dashboard
# Hetzner DynDNS
Ein schlankes, selbst gehostetes Dashboard für mehrere Hetzner-DNS-Zonen und DynDNS-Ziele. Der Container erkennt seine öffentliche IPv4/IPv6 in einem einstellbaren Rhythmus und aktualisiert ausschließlich aktivierte A-/AAAA-Records über die Hetzner Cloud DNS API.
Weboberfläche für mehrere Hetzner-DNS-Zonen, Subdomains und Benutzer. Aktivierte A- und AAAA-Records werden regelmäßig auf die aktuelle öffentliche IP gesetzt.
## Was es kann
## Starten
- Mehrere Hetzner-Domains mit getrennten, verschlüsselten API-Tokens
- Import vorhandener A-/AAAA-Records und Anlegen neuer DynDNS-Hosts
- Reversibles Trennen von DynDNS-Zielen: Hetzner-Records bleiben bestehen und werden im lokalen Archiv angezeigt
- Globale, konfigurierbare IP-Prüfung mit HTTPS-Fallbackquellen
- Live-Countdown bis zum nächsten Scheduler-Lauf und manueller Sofortlauf für Admins
- Beschreibungen lokal und als Hetzner-Record-Kommentar
- Sichere Mehrbenutzerverwaltung:
- `Admin`: vollständige Zonen-, Token-, Updater- und Benutzerverwaltung
- `Mitglied`: ausschließlich explizit freigegebene Domains oder einzelne Subdomains
- SQLite-Datenvolume, Docker Secret für die Token-Verschlüsselung und kein externer Login-Dienst
Die Datei [`compose.yml`](compose.yml) in Portainer, Dockge oder einem anderen Docker-Webinterface als Stack einfügen und starten.
## Schnellstart
1. Secret-Verzeichnis anlegen und einen neuen Schlüssel erzeugen:
```bash
mkdir -p secrets
openssl rand -base64 32 > secrets/dyndns_master_key
chmod 700 secrets
chmod 644 secrets/dyndns_master_key
cp .env.example .env
```
2. Für LAN-Zugriff in `.env` `BIND_ADDRESS` auf die konkrete private IP des Docker-Hosts setzen, zum Beispiel `192.168.178.10`. Verwende im HTTP-LAN-Modus nie `0.0.0.0`.
Die Schlüsseldatei benötigt bei Docker Compose Leserechte für den unprivilegierten Containerprozess. Das Verzeichnis selbst bleibt deshalb auf dem Host mit Modus `700` geschützt; im Container läuft nur der nicht-root DynDNS-Prozess.
3. Starten:
```bash
docker compose up -d --build
```
4. Öffne `http://<host-ip>:8080`, lege den ersten Admin-Benutzer an und verbinde eine Zone mit einem Hetzner Cloud API-Token.
## Produktivbetrieb
Für den Produktivserver gibt es eine separate Compose-Datei, die ein versioniertes Image aus der Gitea Container Registry bezieht und niemals lokal baut. `domain-control-webinterface-prod` ist nur der Name des Container-Pakets; ein zweites Git-Repository ist nicht erforderlich:
Alternativ im ausgecheckten Repository:
```bash
docker compose --env-file .env.production -f compose.production.yml pull
docker compose --env-file .env.production -f compose.production.yml up -d
docker compose up -d
```
Die vollständige Anleitung für Gitea Actions, HTTPS-Reverse-Proxy, Installation, Backups, Updates und Rollbacks steht in [PRODUCTION.md](PRODUCTION.md).
Danach aufrufen:
## Sicherheit
```text
http://IP-DES-DOCKER-HOSTS:8080
```
- Passwörter werden mit Argon2id gehasht.
- Hetzner-Tokens werden mit XChaCha20-Poly1305 verschlüsselt; der Schlüssel liegt als Docker Secret außerhalb des Datenvolumes.
- Cookies sind `HttpOnly` und `SameSite=Strict`; alle schreibenden Formulare verwenden CSRF-Tokens.
- Token-Anzeige verlangt die erneute Eingabe des Admin-Passworts und setzt `Cache-Control: no-store`.
- Unprivilegierte Nutzer sehen niemals API-Tokens, globale IP-Quellen, Update-Historie anderer Domains oder Benutzerverwaltung.
Beim ersten Start werden Datenbank und Verschlüsselungsschlüssel automatisch in getrennten Docker-Volumes angelegt. Es werden keine `.env`-Datei und kein manuell erzeugtes Secret benötigt.
`APP_MODE=lan` ist nur für ein isoliertes, vertrauenswürdiges Netz geeignet. Passwort und API-Token sind bei HTTP auf einem fremden oder geteilten Netz nicht gegen Mitlesen geschützt. Für WLAN mit Gästen oder externen Zugriff setze einen HTTPS-Reverse-Proxy vor den Container und verwende `APP_MODE=https`.
## Das Compose
## Berechtigungen
```yaml
services:
dyndns:
image: git.j-mahler.de/admin/domain-control-webinterface-prod:stable
pull_policy: always
restart: unless-stopped
ports:
- "8080:8080"
volumes:
- dyndns-data:/data
- dyndns-secrets:/secrets
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
Ein Admin legt unter **Benutzer** Konten an und entscheidet pro Mitglied:
volumes:
dyndns-data:
dyndns-secrets:
```
- **Ganze Domain**: Zugriff auf alle aktuellen und später importierten/angelegten DynDNS-Ziele dieser Zone.
- **Einzelne Subdomain**: Zugriff nur auf den konkreten Host, etwa `home.example.de`.
Soll ein anderer Port verwendet werden, muss nur die linke Zahl geändert werden, beispielsweise `9000:8080`.
Mitglieder dürfen ihren freigegebenen Host aktivieren/deaktivieren und dessen Beschreibung pflegen. Sie können keine DNS-Records löschen, Domains importieren, API-Tokens einsehen oder globale Einstellungen verändern.
## Aktualisieren
## Daten und Betrieb
Im Docker-Webinterface das aktuelle Image ziehen und den Stack neu bereitstellen. Auf der Kommandozeile:
Die persistente Datenbank liegt im Docker-Volume `dyndns-data`. Sichere für Backups sowohl das Volume als auch das separate Master-Key-Secret; ohne den Master-Key lassen sich gespeicherte Hetzner-Tokens absichtlich nicht wiederherstellen.
```bash
docker compose pull
docker compose up -d
```
Der Container bietet `/healthz` und `/readyz`. Für eine Aktualisierung ohne Warten auf das Intervall gibt es im Admin-Dashboard **Jetzt aktualisieren**.
Benutzer, Domains und Einstellungen bleiben in `dyndns-data`. Der Schlüssel für gespeicherte API-Tokens liegt in `dyndns-secrets`. Für ein vollständiges Backup müssen beide Volumes gesichert werden.
## Funktionen
- mehrere Domains und getrennt verschlüsselte Hetzner-API-Tokens
- automatischer Import vorhandener A-/AAAA-Records
- DynDNS pro Subdomain und IP-Familie aktivierbar
- lokales Archiv statt Löschen von Hetzner-Records
- frei einstellbares Update-Intervall mit Countdown
- Admin- und Mitgliedskonten mit Domain- oder Subdomain-Rechten
Port 8080 verwendet zunächst unverschlüsseltes HTTP. Den Port daher nur in einem vertrauenswürdigen Netz freigeben und nicht offen ins Internet stellen.