From 45861b091e32020f0cd8a6c99c5d0b76dedc1749 Mon Sep 17 00:00:00 2001 From: Stefan Koelle Date: Sat, 15 Aug 2026 00:00:32 +0200 Subject: [PATCH] README.md --- .moonweb.yml | 6 ++++++ README.md | 56 ++++++++++++++++++++++++++-------------------------- 2 files changed, 34 insertions(+), 28 deletions(-) create mode 100644 .moonweb.yml diff --git a/.moonweb.yml b/.moonweb.yml new file mode 100644 index 0000000..3cf4112 --- /dev/null +++ b/.moonweb.yml @@ -0,0 +1,6 @@ +title: "DynDns Updater" +emoji: "📡" +category: code +subcategory: "Infra Tools" +status: active +stack: [Python, Flask, Requests, fritzconnection, APScheduler] diff --git a/README.md b/README.md index e937869..febfd85 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# dyndns-updater +# 🌐 dyndns-updater Kleiner Docker-Container, der Cloudflare-A-Records (DNS-only) und eine bestehende FreeDNS-Update-URL mit der aktuellen öffentlichen IPv4-Adresse aktuell hält. @@ -6,16 +6,16 @@ FreeDNS-Update-URL mit der aktuellen öffentlichen IPv4-Adresse aktuell hält. Details siehe [SPEC.md](SPEC.md) (Architektur/Design) und [PLAN.md](PLAN.md) (Umsetzungs-Tasks). -## Kurzüberblick +## 📋 Kurzüberblick -- IP wird ausschließlich über die FritzBox TR-064-Schnittstelle ermittelt (nicht aus +- 🏠 IP wird ausschließlich über die FritzBox TR-064-Schnittstelle ermittelt (nicht aus Webhook-Parametern übernommen) -- Trigger: Container-Start, `GET /webhook/update` (kein Auth, rein intern), +- ⏰ Trigger: Container-Start, `GET /webhook/update` (kein Auth, rein intern), Fallback-Polling alle 15 Minuten -- DNS-Update (Cloudflare + FreeDNS) nur bei tatsächlicher IP-Änderung -- Healthcheck-Heartbeat bei jedem Poll-Zyklus, unabhängig von einer IP-Änderung +- 🔄 DNS-Update (Cloudflare + FreeDNS) nur bei tatsächlicher IP-Änderung +- 💚 Healthcheck-Heartbeat bei jedem Poll-Zyklus, unabhängig von einer IP-Änderung -## Quickstart +## 🚀 Quickstart ```bash cp .env.example .env @@ -23,48 +23,48 @@ vim .env # Werte eintragen docker compose up -d ``` -## Konfiguration (`.env`) +## ⚙️ Konfiguration (`.env`) Alle Einstellungen erfolgen ausschließlich über Umgebungsvariablen (siehe [`.env.example`](.env.example)). Pflichtfelder: | Variable | Zweck | | --- | --- | -| `FRITZBOX_HOST`, `_USER`, `_PASSWORD` | TR-064-Zugang zur FritzBox (IP-Quelle) | -| `CLOUDFLARE_API_TOKEN` | Cloudflare-Token (Zone -> DNS -> Edit) | -| `CLOUDFLARE_ZONE_ID` | Cloudflare-Zone | -| `CLOUDFLARE_RECORDS` | Kommagetrennte A-Record-Namen (DNS-only) | +| `FRITZBOX_HOST`, `_USER`, `_PASSWORD` | 🏠 TR-064-Zugang zur FritzBox (IP-Quelle) | +| `CLOUDFLARE_API_TOKEN` | ☁️ Cloudflare-Token (Zone -> DNS -> Edit) | +| `CLOUDFLARE_ZONE_ID` | ☁️ Cloudflare-Zone | +| `CLOUDFLARE_RECORDS` | 📝 Kommagetrennte A-Record-Namen (DNS-only) | Optional: `FREEDNS_UPDATE_URL`, `POLL_INTERVAL_MINUTES`, `HEALTHCHECK_PING_URL`, `TZ`, `LOG_LEVEL`. Die IP kommt ausschließlich aus der FritzBox, nie aus Webhook-Parametern. -### E-Mail-Notification (optional) +### 📧 E-Mail-Notification (optional) Bei IP-Änderung wird eine HTML-E-Mail mit Emojis versendet, wenn SMTP-Konfiguration vorliegt: | Variable | Zweck | | --- | --- | -| `SMTP_HOST` | SMTP-Server (z.B. `smtp.gmail.com`) | -| `SMTP_PORT` | Port (Default: `587`) | -| `SMTP_USER` | SMTP-Login | -| `SMTP_PASSWORD` | SMTP-Passwort | -| `NOTIFY_EMAIL_TO` | Empfänger-Adresse | -| `NOTIFY_EMAIL_FROM` | Absender-Adresse | +| `SMTP_HOST` | 📮 SMTP-Server (z.B. `smtp.gmail.com`) | +| `SMTP_PORT` | 🚪 Port (Default: `587`) | +| `SMTP_USER` | 👤 SMTP-Login | +| `SMTP_PASSWORD` | 🔒 SMTP-Passwort | +| `NOTIFY_EMAIL_TO` | 📬 Empfänger-Adresse | +| `NOTIFY_EMAIL_FROM` | 📤 Absender-Adresse | -## Betrieb +## 🔧 Betrieb -- **State (bewusst ohne Volume, ephemeral):** zuletzt bekannte IP liegt als +- **💾 State (bewusst ohne Volume, ephemeral):** zuletzt bekannte IP liegt als `data/last-known-ip.json` im Container. Bei jedem neu erstellten Container ist der State wieder leer, wodurch beim Start ein Force-Push erzwungen wird. Die Änderung wird erst nach erfolgreichem Update gespeichert. -- **Webhook:** `GET /webhook/update` (kein Auth, intern, Port fest 8090) löst einen Zyklus aus. -- **Healthz:** `GET /healthz` für den Container-Healthcheck (genutzt vom Docker-`HEALTHCHECK`). -- **Healthchecks:** Healthy Ping bei jedem Poll, Failure Ping bei IP-Fehler bzw. Teilfehler. -- **Logs/Wartung:** `docker compose logs -f`; Updates via Watchtower (Label im Compose). +- **🪝 Webhook:** `GET /webhook/update` (kein Auth, intern, Port fest 8090) löst einen Zyklus aus. +- **💓 Healthz:** `GET /healthz` für den Container-Healthcheck (genutzt vom Docker-`HEALTHCHECK`). +- **🏥 Healthchecks:** Healthy Ping bei jedem Poll, Failure Ping bei IP-Fehler bzw. Teilfehler. +- **📊 Logs/Wartung:** `docker compose logs -f`; Updates via Watchtower (Label im Compose). -## Test/Quality +## 🧪 Test/Quality ```bash python3 -m venv .venv && . .venv/bin/activate # virtuelles Umfeld @@ -73,11 +73,11 @@ ruff check . ruff format --check . ``` -## Build +## 🏗️ Build Wird automatisch per GitHub Actions nach `ghcr.io/skoelle/dyndns-updater` gebaut (siehe `.github/workflows/build-and-push.yml`). -## License +## 📄 License Licensed under the [MIT License](LICENSE) - Copyright (c) 2026 Stefan Koelle (https://stefankoelle.de)