Self-hosted Healthchecks (ops/healthchecks/) as the hub for internal cron/job heartbeats. The three host-down/backup watchdogs (Borg pre-hook, baerchen nearline pull, monitoring watchdog #8) deliberately stay on healthchecks.io cloud, since an on-host watcher cannot report a host outage. - frontend_net + dedicated PostgreSQL 18 in healthchecks_internal - native Healthchecks auth; ping/API exempt from Authelia (n8n/Komodo pattern) - registered as middleware_exempt in ops/policy-checks/exceptions.json - docs: DECISIONS, ARCHITECTURE (3.1/4.2/7.6/10), SERVICE_CATALOG, SECRETS_MAP, MASTER_TODO, README index docker compose config validated (exit 0). Not yet deployed: host secret file, appdata dir, Komodo stack + ENV and Gitea webhook remain operator steps. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Typ: Runbook · Stand: 2026-06-23 · Status: vorbereitet (noch nicht deployed)
Healthchecks (self-hosted) — Cron-/Job-Heartbeat-Monitor
Self-gehostete Instanz von Healthchecks
als zentraler Dead-Man's-Switch fuer die internen Jobs und Scripte des
Homelabs: ein Job pingt beim erfolgreichen Lauf eine URL; bleibt der Ping aus,
alarmiert Healthchecks. Damit werden stille Job-Ausfaelle sichtbar, die Docker
("Up"), Prometheus-Blackbox (nur HTTP-Routen) und der Critical-Events-Watcher
(nur die/oom) nicht sehen.
Scope-Entscheidung (wichtig)
Dieser Stack ist bewusst der Hub fuer interne Checks auf einem laufenden Host — Frage: "Lief Job X heute?". Beispiele:
services/posture-check/posture-check.sh(stuendlich / pre-borg)ops/restore-tests/run-restore-checks.sh(Kadenz ausschedule.md)ops/borg-ui/scripts/pre-backup-dumps.sh(Dump-Erzeugung)ops/borg-ui/scripts/gitea-bundle-mirror.sh
Nicht hier: die host-down-/backup-still-Waechter bleiben extern auf healthchecks.io-Cloud (Free-Tier):
| Check | Quelle | Endpoint |
|---|---|---|
| Borg-Pre-Hook | ops/borg-ui/scripts/pre-borg.sh |
healthchecks.io-Cloud |
| baerchen Nearline-Pull | ops/h-drive-nearline/pull-critical-backups.ps1 |
healthchecks.io-Cloud |
| Monitoring-Watchdog (#8) | monitoring/prometheus/alerts.yml (geplant) |
healthchecks.io-Cloud |
Begruendung: Ein Waechter, der auf demselben Unraid-Host laeuft, den er
ueberwacht, kann einen Host-Ausfall nicht melden — er ist dann selbst tot, und
Stille ist nicht von "alles gut" unterscheidbar. Genau diese drei Checks
existieren fuer den Host-/Backup-Stillstand, deshalb muessen sie extern bleiben.
Die Skripte sind endpoint-agnostisch (siehe docs/SECRETS_MAP.md), eine
spaetere Umstellung waere reine URL-Frage — die Architektur-Empfehlung bleibt
aber extern.
Architektur
healthchecks— Web-UI + Ping-Listener,frontend_net, Traefik viahttps://hc.kaleschke.info, native Healthchecks-Auth ohne pauschale Authelia (analog n8n/Komodo): die Ping-Endpunkte/ping/*und die API muessen ohne ForwardAuth erreichbar sein, sonst koennen Jobs nicht melden.healthchecks-postgres— dedizierte PostgreSQL 18, nurhealthchecks_internal(internal: true), niefrontend_net.- SMTP ist bewusst nicht konfiguriert: Login laeuft ueber das Superuser-Passwort, Benachrichtigung ueber die ntfy-Integration. SMTP (GMX) kann spaeter additiv ergaenzt werden, falls E-Mail-Alerts gewuenscht sind.
Secrets (siehe docs/SECRETS_MAP.md)
| Secret | Mechanik |
|---|---|
HEALTHCHECKS_SECRET_KEY |
Komodo Stack-ENV (Django Secret Key) |
HEALTHCHECKS_DB_PASSWORD |
Komodo Stack-ENV (gleicher Wert wie Datei-Secret) |
HEALTHCHECKS_SUPERUSER_EMAIL |
Komodo Stack-ENV (Login-Mail des Erst-Admins) |
HEALTHCHECKS_SUPERUSER_PASSWORD |
Komodo Stack-ENV (Login-Passwort des Erst-Admins) |
healthchecks_postgres_password.txt |
Datei-Secret /mnt/user/appdata/secrets/ → POSTGRES_PASSWORD_FILE |
SECRET_KEY und DB_PASSWORD unterstuetzt das Image nicht als _FILE → Stack-ENV
(Regel aus docs/SECRETS_MAP.md). Das Postgres-Passwort liegt zusaetzlich als
Datei-Secret vor; beide Werte muessen identisch sein.
Pre-Deploy (einmalig, Operator)
- Appdata anlegen:
/mnt/user/appdata/healthchecks/postgres18/. - Datei-Secret erzeugen:
/mnt/user/appdata/secrets/healthchecks_postgres_password.txt(chmod 600), Wert =HEALTHCHECKS_DB_PASSWORD. - In Komodo die vier Stack-ENV-Variablen setzen (
SECRET_KEYz. B. viapython -c "import secrets;print(secrets.token_urlsafe(64))").
Deploy + Pflicht-Webhook
- Stack in Komodo aus Gitea
Micha/homelab-infraanlegen,webhook_enabledan. - Gitea-Webhook auf die neue Stack-ID anlegen
(
http://komodo-core:9120/listener/github/stack/<stack-id>/deploy), Branch-Filtermaster. Pflicht fuer jeden neuen produktiven Stack (docs/WORKFLOW.md). - Test-Delivery ausloesen,
last_status/Komodo-Deploy pruefen.
Post-Deploy
- Login auf
https://hc.kaleschke.infomit Superuser-Mail/-Passwort. - Pro Job einen Check anlegen (Period + Grace passend zur Job-Kadenz, gern als Cron-Ausdruck). Ping-URL kopieren.
- ntfy-Integration: im Check unter Integrations ntfy hinzufuegen,
Server
https://ntfy.kaleschke.info, Topichomelab-alerts(Problem-Alerts) — konsistent mit der bestehenden Alert-Schiene. - Im Job am Ende des erfolgreichen Laufs pingen, z. B.:
Optional
curl -fsS -m 10 --retry 3 "https://hc.kaleschke.info/ping/<uuid>" >/dev/null || true/startam Anfang (misst Laufzeit) und/<uuid>/failim Trap.
Rollback
- Letzter stabiler Git-Stand: Stack existiert noch nicht — Rollback = Stack in
Komodo stoppen/destroyen, Repo-Pfad
ops/healthchecks/pergit rmzuruecknehmen, Gitea-Webhook deaktivieren. - Datenpfad
/mnt/user/appdata/healthchecks/postgres18bleibt unberuehrt und ist jederzeit loeschbar (reine Check-Metadaten, kein kritischer Datentopf — die Pings selbst sind in den Jobs definiert). - Secrets/ENV: bei Abbau die vier Stack-ENV + die Datei-Secret entfernen.
Image-Pinning
healthchecks/healthchecks:v4.2@sha256:6b5f59… ist auf den am 2026-06-23 ueber
die Docker-Hub-API ermittelten Manifest-Digest gepinnt. Beim ersten Pull den
real laufenden Digest gegenpruefen und bei Abweichung im Repo nachziehen
(docs/WORKFLOW.md Abschnitt Image-Versionierung).