--- type: adr id: "0015" status: accepted date: 2026-08-13 supersedes: null superseded_by: null related: [docs/issues/0048-wikijs-in-der-suite-deployen.md, docs/adr/0014-wikijs-loest-docusaurus-ab.md, docs/adr/0001-gitlab-kanonisch-push-mirror.md] --- # 0015 — Wiki.js Git-Storage: Inhalt fließt Cluster→Gitea→kanonisiert nach git.lab ## Kontext ADR-0014 macht docs-as-code zur harten Anforderung: der Wiki-Inhalt liegt in git. #0048 hielt dafür fest, ein **git.lab**-`wiki`-Repo anzulegen, „gespiegelt wie die übrigen", und es als Wiki.js-Git-Storage mit bidirektionalem Sync einzubinden. Beim Bau (2026-08-13) zeigt sich: das ist so **nicht machbar**. Wiki.js läuft im Hetzner-Cluster, und der erreicht git.lab bewusst **nicht** — `git.lab` löst aus dem Pod nicht auf; nur Gitea (`rohana.axion1337.de`) ist per HTTPS erreichbar (verifiziert). Diese Lab-Unabhängigkeit ist Absicht (ADR-0001, ADR-0004): die Produktion darf nicht von einem Host abhängen, der nur im Lab antwortet. Der Schreiber des Inhalts sitzt also im Cluster und kann git.lab nicht beschreiben. ## Optionen - **A — Cluster→git.lab öffnen.** Verworfen: hebelt die bewusste Lab-Unabhängigkeit aus (ADR-0001), koppelt die Produktion ans Lab. - **B — Nur Gitea, kein git.lab-Kanon.** Wiki.js schreibt in ein Gitea-Repo, fertig. Verworfen: der Inhalt hätte keinen kanonischen git.lab-Stand — widerspricht ADR-0001. - **C — Wiki.js→Gitea, CI kanonisiert Gitea→git.lab.** Wiki.js pusht in ein Gitea-Repo; ein geplanter CI-Job auf git.lab holt den Stand und schreibt ihn nach git.lab. Das ist **dasselbe Muster**, das für den TURN-Rotations-CronJob bereits akzeptiert ist (der einzige verbliebene Cluster-Schreibvorgang nach Gitea, siehe gitops-CLAUDE.md / `canonize_rotation`). Gewählt. ## Entscheidung Der Wiki.js-Git-Storage zielt auf ein **Gitea-Repo** (`sorb/wiki`) über HTTPS mit einem **dedizierten Deploy-PAT**. Der Inhalt wird per geplantem CI-Job Gitea→git.lab **kanonisiert**, analog zu `canonize_rotation`. Die Richtung ist gegenüber dem üblichen Push-Mirror (git.lab→Gitea) **umgekehrt**, weil der Schreiber im Cluster sitzt — das ist eine bewusste, dokumentierte Ausnahme zu ADR-0001, kein Regelbruch. ## Konsequenzen - **Leichter:** reproduzierbar und lab-unabhängig; nutzt ein etabliertes Muster statt eines neuen Sonderwegs; kein Netz-Umbau am Cluster. - **Schwerer:** ein zweiter Cluster→Gitea-Schreibpfad, der gepflegt sein will; braucht den Kanonisierungs-Job (Vorlage `canonize_rotation`); ein dedizierter PAT liegt im Cluster-SOPS (eigene Rotation). - **Voraussetzungen (sorb):** Gitea-Repo `sorb/wiki` (privat) anlegen; dedizierten Deploy-PAT (write:repository) bereitstellen. Beides kann der Agent nicht selbst — der vorhandene Push-Token darf keine Repos anlegen. - **Später zu klären:** ob das Content-Repo unter eine Gruppe mit eigenem Mirror gehört; ob echter bidirektionaler Sync (Edits in git) gewollt ist oder push-only genügt. ## Umsetzungsstand (2026-08-13) Wiki.js→Gitea ist **live und End-to-End verifiziert**: Repo `sorb/ThreadNetWiki` (mit `main` initialisiert), dedizierter Deploy-PAT im SOPS-Secret `wikijs-git-secret`, Storage-Target `operational`, Seite anlegen/löschen propagiert nach Gitea. Ausstehend ist nur die zweite Hälfte — der **Kanonisierungs-Job Gitea→git.lab** (Vorlage `canonize_rotation`); dafür fehlt die Entscheidung, in welches git.lab-Repo kanonisiert wird.