From 1c89927b181f853d0791af223678852e116833b6 Mon Sep 17 00:00:00 2001 From: Stefan Koelle Date: Fri, 7 Aug 2026 11:31:39 +0200 Subject: [PATCH] README.md and AGENTS.md --- AGENTS.md | 43 +++++++++++++++++++++++++++++++++++++++++++ README.md | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 AGENTS.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..67b0dca --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,43 @@ +# AGENTS.md + +## Projekt + +Kleiner Docker-Container, der Cloudflare-A-Records (DNS-only) + eine FreeDNS-URL mit der +aktuellen öffentlichen IPv4-Adresse pflegt. IP wird ausschließlich über die FritzBox +TR-064-Schnittstelle ermittelt. + +Kontext: [`SPEC.md`](SPEC.md) (Design), [`PLAN.md`](PLAN.md) (Tasks), +[`README.md`](README.md) (Betrieb). + +## Struktur + +- `app/` – Kernmodule (Python 3.12) + - `config.py` – ENV-basierte Konfiguration + Validierung + - `state.py` – persistierte letzte IP (`/data/last-known-ip.json`) + - `fritzbox.py` – IP-Ermittlung via TR-064 (Retry/Backoff) + - `cloudflare.py` – A-Record-Update (DNS-only) + - `freedns.py` – FreeDNS-Update-Call + - `healthcheck.py` – Healthchecks-Pings + - `main.py` – Flask-Webhook (`/webhook/update`, `/healthz`) + Poll-Scheduler +- `.env.example` – Referenz aller ENV-Variablen (Pflicht: FRITZBOX_*, CLOUDFLARE_*) + +## Befehle + +- Tests: keine Test-Suite vorhanden +- Lint/Format: `ruff check .` und `ruff format --check .` (in `.venv` via + `python3 -m venv .venv && . .venv/bin/activate`) +- Lokal: `python -m app.main` (im `.venv`, deps aus `requirements.txt`) +- Container: `docker compose up -d` + +## Konventionen + +- CREDENTIALS NIE committen. `.env` und `data/` sind gitignored – nie mit `-f` hinzufügen. +- Keine Co-Autoren in Commits. +- Keine Kommentare im Code außer auf Nachfrage. +- Python-Code mit Ruff formatieren (line-length 100, double quotes). +- Änderungen an `SPEC.md`/`PLAN.md`/`README.md` mitziehen, wenn sich Design/Betrieb ändert. + +## Lizenz + +MIT – Copyright Stefan Koelle (https://stefankoelle.de). Lizenz-Header bei neuen +Quellcode-Dateien ergänzen, wenn möglich mit `/add-license`. diff --git a/README.md b/README.md index 8dec321..c456053 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,40 @@ vim .env # Werte eintragen docker compose up -d ``` +## 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) | + +Optional: `FREEDNS_UPDATE_URL`, `WEBHOOK_PORT`, `POLL_INTERVAL_MINUTES`, +`HEALTHCHECK_PING_URL`, `TZ`, `LOG_LEVEL`. Die IP kommt ausschließlich aus der +FritzBox, nie aus Webhook-Parametern. + +## Betrieb + +- **State:** zuletzt bekannte IP liegt als `data/last-known-ip.json` (Volume) – + Änderung wird erst nach erfolgreichem Update gespeichert. +- **Webhook:** `GET /webhook/update` (kein Auth, intern) löst einen Zyklus aus. +- **Healthz:** `GET /healthz` für Container-Healhcheck. +- **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 + +```bash +python3 -m venv .venv && . .venv/bin/activate # virtuelles Umfeld +pip install -r requirements.txt -r requirements-dev.txt +ruff check . +ruff format --check . +``` + ## Build Wird automatisch per GitHub Actions nach `ghcr.io/skoelle/dyndns-updater` gebaut