# Back-ups, herstel en beheer op Unraid Deze gids beschrijft de M7-functionaliteit: back-ups maken, een back-up herstellen naar een schone omgeving, en de operationele controles rond een Unraid-implementatie. Geschreven voor beheerders/operators, niet voor eindgebruikers. Er is bewust geen scherm in de webapplicatie voor back-upbeheer — dit gebeurt via de API (back-up maken/ lijst tonen) en via een aparte opdrachtregelmodus van dezelfde container-image (herstellen), nooit via een knop in de draaiende applicatie zelf. ## Een back-up maken ```bash curl -X POST https://hub.example/api/v1/admin/backups \ -H "X-CSRF-Token: " -b cookies.txt ``` Dit maakt synchroon een volledige back-up: elke databasetabel (via een schema- onafhankelijke binaire kopie, geen externe `pg_dump`-tool nodig) plus elk content-adresseerbare bijlagebestand, met een `manifest.json` dat per bestand een SHA-256-hash bevat. Elk bestand wordt na het schrijven opnieuw gehasht en vergeleken vóór de back-up zichtbaar wordt — een back-up die deze controle niet doorstaat, wordt nooit gepubliceerd en vervangt dus nooit de laatst bekende goede back-up. ```bash curl https://hub.example/api/v1/admin/backups -b cookies.txt ``` geeft de lijst van voltooide back-ups terug (nieuwste eerst), met alleen veilige, niet-herleidbare informatie (geen bestandspaden, geen connectiegegevens). ### Bewaarbeleid Standaard worden de **14 nieuwste** voltooide back-ups bewaard (instelbaar via `KnowledgeHub__Backup__RetainedCount`); de allerlaatste back-up wordt nooit verwijderd, ook niet als dat aantal wordt overschreden. Back-ups blijven op dezelfde schijf/pool als de applicatie staan — kopieer ze periodiek naar een onafhankelijke opslaglocatie; een back-up op dezelfde schijf alleen is geen rampenherstel. ## Een back-up herstellen Herstel is bewust **nooit** bereikbaar via de draaiende applicatie zelf — een draaiende applicatie die tegelijk verkeer verwerkt én haar eigen database overschrijft, is precies het scenario dat vermeden moet worden. In plaats daarvan draait dezelfde image in een aparte, kortstondige opdrachtregelmodus, gericht op een **schone doelomgeving** (nooit de productie-instantie). ### Stap 1 — doeldatabase voorbereiden (alleen migreren) ```bash docker run --rm \ --network itworx-knowledge-hub_knowledge-hub-internal \ -e KnowledgeHub__Database__Host= \ -e KnowledgeHub__Database__Name= \ -e KnowledgeHub__Database__Username= \ -e KnowledgeHub__Database__Password= \ itworx/knowledge-hub:local \ dotnet ItWorx.KnowledgeHub.Api.dll --migrate-only ``` Gebruik hier bewust `--migrate-only`, niet een gewone opstart: een gewone opstart maakt als bijwerking meteen de installatierij aan (dezelfde rij die bij een eerste installatie hoort), waardoor de doeldatabase niet meer "leeg" is tegen de tijd dat herstel start. `--migrate-only` past uitsluitend het schema toe en sluit daarna direct af. ### Stap 2 — herstellen Maak eerst een **beschrijfbare herstelkopie** van de gekozen back-up; herstel neemt een exclusieve opslaglease en schrijft achteraf een herstelbewijs naast het manifest. Geef de CLI de doelconnectie via een door de operator beheerd geheimenbestand, niet via een argument met het wachtwoord erin. Op Unix moet dat bestand alleen voor de restoregebruiker leesbaar zijn (`chmod 600` of `chmod 400`); op Windows beperk je de ACL tot de restore- operator/serviceaccount. Het bestand bevat één PostgreSQL-connectiereeks. De integriteitssleutel moet eveneens beschikbaar zijn in de geconfigureerde Keys-map. Haal de exacte `backup-integrity.key` uit beschermde externe escrow; herstel vertrouwt geen sleutel die alleen in de back-upkopie zit. De restore verifieert de manifest- handtekening en kopieert de vermelde bestanden eerst naar een privé-stagingmap binnen het lege doelbijlagenvolume. Reserveer daar vrije ruimte voor ten minste de volledige back-upinhoud. De restore gebruikt uitsluitend die geverifieerde snapshot. ```bash docker run --rm \ --network itworx-knowledge-hub_knowledge-hub-internal \ -v :/var/lib/knowledge-hub/backups:rw \ -e KnowledgeHub__Paths__Backups=/var/lib/knowledge-hub/backups \ -v :/var/lib/knowledge-hub/keys:ro \ -e KnowledgeHub__Paths__Keys=/var/lib/knowledge-hub/keys \ -v :/run/secrets/restore-target-connection:ro \ -v :/var/lib/knowledge-hub/attachments \ itworx/knowledge-hub:local \ dotnet ItWorx.KnowledgeHub.Api.dll \ --restore \ --backup-id= \ --target-connection-file=/run/secrets/restore-target-connection \ --target-attachments=/var/lib/knowledge-hub/attachments ``` De echte herstel-drill haalt de back-up via SSH op, maar leest de integriteitssleutel uit een lokaal door de operator beheerd escrowbestand. Geef alleen het bestandspad mee; de drill maakt tijdens uitvoering een tijdelijke kopie met modus `0600` en verwijdert die bij opruimen: ```bash KNOWLEDGE_HUB_BACKUP_INTEGRITY_KEY_FILE=/secure/escrow/backup-integrity.key \ bash scripts/v2-r4-real-backup-restore-drill.sh ``` De doeldatabase moet **leeg** zijn — herstel weigert expliciet als er al rijen in staan, om nooit per ongeluk bestaande gegevens te vermengen met herstelde gegevens. Het proces rapporteert per tabel het aantal herstelde versus verwachte rijen, het aantal herstelde bijlagen, en sluit af met `GESLAAGD` of `MISLUKT` (afsluitcode 0 respectievelijk 1). Een `MISLUKT`-resultaat laat expliciet zien welke tabel niet overeenkomt — er wordt nooit stilzwijgend een onvolledig herstel als geslaagd gerapporteerd. Providerfoutdetails worden niet afgedrukt omdat die connectiegegevens kunnen bevatten. ## Opstartgedrag en migraties Bij elke opstart: 1. De applicatie weigert te starten als de database al een migratie heeft toegepast die deze build niet kent (bijvoorbeeld na een terugzetting naar een oudere image-versie tegen een nieuwere database) — dit voorkomt dat de applicatie onbedoeld tegen een onbekende schemavorm gaat werken. 2. Normale voorwaartse migratie (een oudere database die bijwerkt naar een nieuwere applicatieversie) blijft het gewone pad en gebeurt automatisch bij opstart. ## Statuscontroles - `GET /health/live` — altijd anoniem bereikbaar; faalt nooit vanwege een tijdelijk onbereikbare database. Gebruik dit voor de container-gezondheidscontrole. - `GET /health/ready` — anoniem bereikbaar maar geeft alleen een minimale status terug (geen details): controleert databaseverbinding, of alle migraties zijn toegepast, en of alle geconfigureerde opslagpaden beschrijfbaar zijn. - `GET /api/v1/system/info` — vereist beheerdersaanmelding. Toont productversie, schemaversie, commit en uptime — gebruik dit na een herstart/upgrade om te bevestigen welke versie en welk schema daadwerkelijk draait. ## Logboeken In productie schrijft de applicatie gestructureerde JSON-logregels naar stdout/stderr, elk met een correlatie-ID zodat alle logregels van één aanvraag samen te herleiden zijn. Wachtwoorden, ruwe tokens, cookies, autorisatie-headers, connectiereeksen en paginainhoud worden nooit gelogd. Logrotatie gebeurt op Docker/Unraid-niveau, niet binnen de applicatie.