Zweiter Erstlauf 2026-06-03 scheiterte weiterhin mit 503, obwohl
config.php korrekt gepatcht war.
Ursache: Unraid's FUSE/shfs-Dateisystem auf User-Shares ignoriert
chown -R 33:33 still — Dateien bleiben bei sshd:sshd. Der
Nextcloud-Entrypoint versucht intern chmod/chown auf /var/www/html und
/var/www/html/data, was mit no-new-privileges:true blockiert wird.
Fix:
- no-new-privileges vom restoretest-nextcloud Container entfernt,
damit der Entrypoint Rechte im Container selbst setzen kann
(Test-Postgres und Test-Redis behalten no-new-privileges)
- Host-seitiger chown durch chmod a+rwX ersetzt (funktioniert auf shfs)
- Vertretbar im isolierten Smoke-Kontext (127.0.0.1, Wegwerf-Daten,
kein Traefik)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Erstlauf 2026-06-03 scheiterte mit dauerhaft 503. config.php-Patching
(Redis-Host + trusted_domains) war korrekt, aber Nextcloud konnte die
restaurierten Dateien nicht lesen/schreiben: "chmod(): Operation not
permitted at OC_Util.php#486".
Ursache: Borg-Extract ueber den borg-ui Container legt Dateien mit dem
borg-ui-User (sshd o.ae.) an. Nextcloud im Container laeuft als
www-data (UID 33). Mit no-new-privileges:true scheitert jeder chmod/
chown-Versuch im Container.
Fix: chown -R 33:33 auf html/ und data/ nach dem Extract, bevor der
Nextcloud-Container startet.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Erstlauf 2026-06-03 scheiterte mit 503: Redis-Host war noch auf dem
produktiven 'nextcloud-redis' statt 'restoretest-nextcloud-redis', und
trusted_domains enthielt kein 127.0.0.1 (Nextcloud blockt mit
"Access through untrusted domain").
Ursache: das sed-Pattern fuer Redis versuchte den ganzen Array-Block
einzeilig zu ersetzen, traf aber das PHP-Mehrzeilenformat nicht. Und
das trusted_domains-sed fand das Schliessmuster nicht zuverlaessig.
Fix:
- Redis-Host separat per sed patchen (nur den 'host'-Wert im Block)
- trusted_domains per PHP-CLI rewrite (robuster als sed auf PHP-Arrays)
- Fallback auf sed fuer Hosts ohne php
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Nextcloud-Restore-Test nach dem Muster der anderen Restore-Smokes:
- Borg-Extract von html (App-Code + config.php) und nextcloud.dump
- pg_restore in isoliertes Test-Postgres (mit Retry-Schleife)
- config.php wird im Restore-Lab auf Test-DB-Credentials gepatcht
(produktive Secrets werden nicht gemountet)
- Nextcloud startet gegen restaurierte Daten + Test-Redis
- Smoke prueft HTTP /status.php und occ status (maintenance mode)
- Produktive Nutzdaten unter /mnt/user/documents/nextcloud-data
werden bewusst NICHT gemountet (zu gross fuer regelmaessigen Smoke)
Erster Lauf steht aus und braucht Operator-Freigabe auf dem Host.
Dispatcher und ntfy-Wrapper um Nextcloud erweitert.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Erstlauf 2026-06-03 hat einen by-design-Konflikt offengelegt: pg_restore des
produktiven postgresql17-authelia.dump in eine Test-Instanz mit Wegwerf
AUTHELIA_STORAGE_ENCRYPTION_KEY scheitert im Authelia-Startup-Check mit
"the configured encryption key does not appear to be valid for this database".
Productive Storage-Werte werden mit dem produktiven Key verschluesselt; ein
Wegwerf-Key kann sie nicht entschluesseln. Smoke ist deshalb explizit auf
Config-Restore + Boot reduziert, nicht Daten-Decrypt.
Zwei Nebenbefunde aus demselben Lauf:
- AUTHELIA__SERVER__ADDRESS (Doppel-Underscore) wurde von Authelia 4.39
abgelehnt ("configuration environment variable not expected"). ENV
entfernt; server.address kommt eh aus der generierten configuration.yml.
- ntp-Startup-Check schlug fehl ("Could not determine the clock offset
... lookup time.cloudflare.com on 127.0.0.1:53: server misbehaving"),
weil das isolierte Test-Compose-Netz keinen DNS-Resolver fuer NTP hat.
Neuer Test-Config-Block setzt ntp.disable_startup_check: true.
Doku nachgezogen (Plan + Runbook): Encryption-Key-Konflikt ist explizit
als "nicht Teil dieses Smokes" dokumentiert; Fehler-Matrix hat Eintraege
fuer Doppel-Underscore-ENV und NTP-Lookup.
Frische des produktiven authelia-Dumps wird unveraendert ueber
check-restore-freshness.sh ueberwacht; Daten-Decrypt-Drill ist eine eigene
DR-Aufgabe mit kontrollierter Schluessel-Verwendung.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Authelia 4.39 verlangt: ohne access_control.rules muss default_policy
'two_factor' oder 'one_factor' sein. 'bypass' war nur historisch zulaessig,
mit 4.39 schlaegt config validate fehl mit "'default_policy' option
'bypass' is invalid: when no rules are specified it must be 'two_factor'
or 'one_factor'". /api/health ist public und laeuft nicht durch
access_control - die Smoke-Semantik bleibt unveraendert.
Beobachtet im Erstlauf 2026-06-03 nach Refactor auf Minimal-Testkonfig
(Commits 541c7be..440000c). Mit diesem Fix sollte 'authelia config
validate' durchlaufen; HTTP /api/health-Smoke ist der Folgeschritt.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Six files had outdated status notes that the F-09 first run on
2026-05-30 made wrong:
- ops/restore-tests/komodo-bootstrap-runbook.md: "Erster echter Lauf
steht noch aus" -> first run confirmed
- ops/restore-tests/komodo-bootstrap-plan.md: "Noch offen vor dem
ersten echten Lauf" section -> "Bestaetigte Laeufe" table with
the --what-if and --keep-data runs
- ops/restore-tests/immich-runbook.md: status note still said
"Erster echter Lauf steht noch aus" although the Immich first run
was 2026-05-27; correcting in the same sweep
- docs/AUDIT_2026-05-25_TODO.md: Sprint 2 entry on Komodo bootstrap
path no longer carries the "Trockenlauf-Skript bleibt als offene
Folgeaufgabe" tail
- docs/SERVICES_RECOVERY.md: replaced the "Trockenlauf-Idee (Doku-only,
nicht ausgefuehrt)" section with the confirmed repo-script flow and
marked the two "Naechste Aufgaben" rows about the dry-run as done
- docs/RESTORE_DRILL_ROUTINE.md: Q2 2026 DR-Sanity-Check entry now
splits Komodo-Bootstrap-Pfad (done) from the two still-open items
(Gitea bundles, secrets inventory)
No behavior change, only documentation consistency.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Mirror of the Immich restore-test pattern for the Komodo bootstrap
anchor. Brings up a throwaway komodo-mongo + komodo-core +
komodo-periphery under project restoretest-komodo, isolated from
production:
- same image digests as production (mongo:7.0.32, komodo-core:2,
komodo-periphery:2) to prove compose-level bootstrap compatibility
- restore-lab paths under /mnt/user/backups/restore-lab/komodo
- 127.0.0.1:19120 only, no LAN bind, no Traefik, no Authelia
- test periphery runs WITHOUT docker.sock mount and WITHOUT
/mnt/user/services mount; cannot manage productive containers
- KOMODO_* secrets are throwaway placeholders hardcoded in the test
compose; productive secrets never enter this path
Smoke test: compose config valid, mongo healthy, mongo auth-ping
with test creds, komodo-core HTTP 200/302/303/401, periphery
container running. Report under restore-reports/komodo-bootstrap-*.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
New docs/RESTORE_DRILL_ROUTINE.md introduces a three-stage model:
weekly freshness check, monthly/bimonthly mini-restores, quarterly
DR sanity check. Tracks confirmed mini-restores (Vaultwarden, Gitea,
Paperless 2026-05-07; Immich 2026-05-27) and rotates services by
quarter Q1-Q4. Includes ten-point DR sanity check and abort rules
that point at the drift runbook. No host schedule is created; the
existing ops/restore-tests/schedule.md now references this routine
as the source for quarterly assignment.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>