Initial curated RAGcore source from c16667f0c9397e2bfc8dd0255b114fba23c8d05e
This commit is contained in:
commit
7ca726caf2
659 files changed
+98171
No files matched your search
@@ -0,0 +1,22 @@
|
||||
# Backup and Restore
|
||||
|
||||
## Backupset
|
||||
|
||||
1. PostgreSQL consistente dump/base backup.
|
||||
2. Immutable blobs en parsed artifacts.
|
||||
3. Qdrant collection snapshots.
|
||||
4. Collection aliases en profile/configexport.
|
||||
5. Secret/configmanifest zonder plaintext secretwaarden.
|
||||
6. Softwareversie, migration revision en checksums.
|
||||
|
||||
## Restorevolgorde
|
||||
|
||||
Secrets/config -> PostgreSQL -> blobs -> parsed artifacts -> Qdrant snapshots -> aliases -> reconciliation -> golden evaluations -> security tests -> traffic.
|
||||
|
||||
## Validatie
|
||||
|
||||
Een backup telt pas als geslaagd na automatische restore naar lege tijdelijke omgeving. Controleer row/point/blob counts, referential integrity, sampled hashes, citations, golden queries en cross-space denial.
|
||||
|
||||
## RPO/RTO V1
|
||||
|
||||
Startdoel: dagelijkse volledige consistente backup plus incrementele blobbackup; RPO 24 uur, RTO 4 uur. Later alleen aanpassen op gemeten noodzaak.
|
||||
@@ -0,0 +1,138 @@
|
||||
# Unraid Deployment
|
||||
|
||||
## Opslag
|
||||
|
||||
Active state gebruikt directe SSD/NVMe poolpaden:
|
||||
|
||||
```text
|
||||
/mnt/<pool>/appdata/ragcore/postgres
|
||||
/mnt/<pool>/appdata/ragcore/qdrant
|
||||
/mnt/<pool>/appdata/ragcore/blobs
|
||||
/mnt/<pool>/appdata/ragcore/parsed
|
||||
/mnt/<pool>/appdata/ragcore/tmp
|
||||
```
|
||||
|
||||
Gebruik voor PostgreSQL/Qdrant **niet** `/mnt/pool/appdata/...`. Backupexports mogen naar `/mnt/pool/backups/ragcore`.
|
||||
|
||||
## Deployment
|
||||
|
||||
- Maak `.env` uit voorbeeld en genereer unieke secrets.
|
||||
- Zet `RAGCORE_STATE_ROOT` naar direct poolpad.
|
||||
- Start Compose; houd `models` profiel uit wanneer centrale Ollama bestaat.
|
||||
- Maak één dedicated extern Docker-netwerk voor Nginx Proxy Manager en RAGCore.
|
||||
- Configureer Nginx Proxy Manager naar `ragcore-app:8080` op dat netwerk.
|
||||
- Publiceer de app-hostpoort uitsluitend op `127.0.0.1`; stuur nooit bearer-tokens
|
||||
rechtstreeks over een LAN-HTTP-poort.
|
||||
- Koppel Authentik/OIDC in productie.
|
||||
- Publiceer geen PostgreSQL/Qdrant/Ollamapoort.
|
||||
|
||||
### Reverse-proxy trust boundary
|
||||
|
||||
Productie accepteert `X-Forwarded-*` uitsluitend van de expliciet ingestelde
|
||||
proxy-IP/CIDR. Wildcardtrust (`*`, `0.0.0.0/0`, `::/0`) wordt bij startup
|
||||
geweigerd. Een dedicated netwerk voorkomt dat een willekeurige container binnen
|
||||
een breed gedeeld subnet als vertrouwde proxy kan optreden.
|
||||
|
||||
Eenmalige netwerkinitialisatie voor de gedocumenteerde Unraid-topologie:
|
||||
|
||||
```bash
|
||||
docker network create --driver bridge --subnet 172.30.50.0/29 ragcore-proxy
|
||||
docker network connect --ip 172.30.50.2 ragcore-proxy NginxProxyManager
|
||||
```
|
||||
|
||||
Voeg aan `.env` toe:
|
||||
|
||||
```dotenv
|
||||
RAGCORE_PUBLIC_BASE_URL=https://rag.example.com
|
||||
RAGCORE_TRUSTED_PROXY_IPS=172.30.50.2
|
||||
RAGCORE_PROXY_NETWORK=ragcore-proxy
|
||||
```
|
||||
|
||||
De productie-Compose koppelt `app` met alias `ragcore-app` aan dit externe
|
||||
netwerk. Stel de Nginx Proxy Manager upstream in op scheme `http`, hostname
|
||||
`ragcore-app`, port `8080`. Controleer HTTPS vóór de oude upstream wordt
|
||||
verwijderd. De loopback-hostpoort blijft alleen voor lokale healthchecks en
|
||||
rollbackdiagnose beschikbaar. Vertrouw bij voorkeur uitsluitend het statische
|
||||
IP van Nginx Proxy Manager. Een CIDR is alleen correct wanneer elk adres in dat
|
||||
bereik een geautoriseerde proxy is; een Docker-netwerkgateway valt ook binnen
|
||||
het subnet en mag daarom niet impliciet forwardingheaders mogen aanleveren.
|
||||
|
||||
## Preflight
|
||||
|
||||
Beschikbare disk/RAM, filesystem, ownership UID 10001, klok/NTP, backupdoel, modelendpoint en reverse-proxy headers controleren:
|
||||
|
||||
```bash
|
||||
python3 scripts/unraid_preflight.py \
|
||||
--state-root /mnt/<pool>/appdata/ragcore \
|
||||
--backup-dir /mnt/pool/backups/ragcore \
|
||||
--ollama-url http://<ollama-host>:11434 \
|
||||
--base-url https://ragcore.example.com
|
||||
```
|
||||
|
||||
Blokkerende bevindingen (`[BLOCK]`, o.a. een actieve `/mnt/user`-status voor
|
||||
`--state-root`) stoppen de deploy; `[WARN]` is informatief (bijv. klok-sync
|
||||
niet vast te stellen buiten een Linux-host).
|
||||
|
||||
## Operational runbook
|
||||
|
||||
Alle commando's hieronder gaan uit van `compose.yaml` + `compose.production.yaml`
|
||||
samen; nooit `compose.test.yaml` of `compose.restore-test.yaml` in productie
|
||||
(die zijn uitsluitend voor lokale/testomgevingen).
|
||||
|
||||
### Start (eerste deploy of na reboot)
|
||||
|
||||
```bash
|
||||
cp .env.example .env # eenmalig; vul echte secrets en RAGCORE_STATE_ROOT in
|
||||
python3 scripts/unraid_preflight.py --state-root /mnt/<pool>/appdata/ragcore --backup-dir /mnt/pool/backups/ragcore
|
||||
docker compose -f compose.yaml -f compose.production.yaml up -d
|
||||
python3 scripts/check_app_health.py --base-url https://rag.example.com
|
||||
```
|
||||
|
||||
### Stop
|
||||
|
||||
```bash
|
||||
docker compose -f compose.yaml -f compose.production.yaml stop
|
||||
```
|
||||
|
||||
Gebruik `down` (in plaats van `stop`) alleen wanneer je ook de containers en
|
||||
het (interne) netwerk wilt verwijderen; volumes/bind mounts (dus alle data)
|
||||
blijven in beide gevallen ongemoeid tenzij `-v` wordt toegevoegd -- gebruik
|
||||
`-v` nooit in productie.
|
||||
|
||||
### Upgrade
|
||||
|
||||
```bash
|
||||
# 1. Backup vóór elke upgrade (zie runbooks/BACKUP.md)
|
||||
python3 scripts/backup.py --backup-root /mnt/pool/backups/ragcore
|
||||
|
||||
# 2. Nieuwe image ophalen/bouwen en migreren
|
||||
git pull # of: nieuwe release-ZIP uitpakken
|
||||
docker compose -f compose.yaml -f compose.production.yaml build app worker mcp
|
||||
docker compose -f compose.yaml -f compose.production.yaml run --rm app alembic upgrade head
|
||||
|
||||
# 3. Rollend herstarten
|
||||
docker compose -f compose.yaml -f compose.production.yaml up -d
|
||||
python3 scripts/check_app_health.py --base-url https://rag.example.com
|
||||
```
|
||||
|
||||
Zie `docs/09_OPERATIONS/UPGRADE_STRATEGY.md` voor het volledige beleid
|
||||
(o.a. backward-compatibele migraties, nooit in-place index-upgrades).
|
||||
|
||||
### Rollback
|
||||
|
||||
Applicatie-rollback (voorkeur, geen restore):
|
||||
|
||||
```bash
|
||||
git checkout <vorige-release-tag-of-commit> # of: vorige release-ZIP
|
||||
docker compose -f compose.yaml -f compose.production.yaml build app worker mcp
|
||||
docker compose -f compose.yaml -f compose.production.yaml up -d
|
||||
```
|
||||
|
||||
Migraties zijn per beleid backward-compatible voor minstens één release, dus
|
||||
een applicatie-rollback tegen de nieuwere schema-versie werkt zonder
|
||||
`alembic downgrade`. Een volledige restore vanaf backup is het laatste
|
||||
redmiddel, niet de normale rollback-weg -- zie `runbooks/RESTORE.md`.
|
||||
|
||||
Index-/profielactivatie-rollback (indien van toepassing) gaat via
|
||||
`/admin/profiles` (M4-07's `ProfileActivationService`), niet via deze
|
||||
Compose-commando's.
|
||||
@@ -0,0 +1,130 @@
|
||||
# Upgrade Strategy
|
||||
|
||||
## Applicatie
|
||||
|
||||
Build immutable image, run migrations/preflight, deploy, verify health and smoke tests. Database migrations are backward compatible for at least one application rollout whenever practical.
|
||||
|
||||
## Embedding/index
|
||||
|
||||
Never in place. Register new profile, build shadow collection, evaluate, activate alias, retain old build for rollback.
|
||||
|
||||
## PostgreSQL/Qdrant
|
||||
|
||||
Pin exact supported versions, read release notes, test backup restore and application suite in staging/temporary environment, then maintenance deployment. No automatic major upgrades.
|
||||
|
||||
## Rollback
|
||||
|
||||
Application image rollback plus compatible migration strategy; index alias rollback for retrieval; config/profile activation history. Restore is last resort, not ordinary rollback.
|
||||
|
||||
## Upgrade naar 1.2.1
|
||||
|
||||
Deze release bundelt drie rondes: SOURCE-CONVERGENCE (migratie `0017`),
|
||||
OPERATIONS-ISOLATION (`0018`) en RELEASE-CLEANUP (`0019`). Eén
|
||||
`alembic upgrade head` voert ze in volgorde uit; de stappen hieronder
|
||||
beschrijven wat er per ronde verandert en wat je vóór de uitrol moet zetten.
|
||||
|
||||
### SOURCE-CONVERGENCE (`0017`)
|
||||
|
||||
1. **Eerst configureren, dan uitrollen.** `RAGCORE_SOURCE_ROOTS` is een expliciete
|
||||
allowlist van server-side paden die een Folder- of Git-bron mag lezen, en is
|
||||
*leeg by default* -- fail closed. Zolang die leeg is kan geen enkele
|
||||
filesystem-bron worden aangemaakt of gesynchroniseerd, en falen bestaande
|
||||
folder/Git-syncs **terminaal** (`source path is outside every allowed source
|
||||
root`). Zet de waarde dus vóór de uitrol, met de paden zoals de *worker* ze
|
||||
ziet, en zorg dat elk pad ook read-only in de worker gemount is
|
||||
(`RAGCORE_SOURCE_MOUNT` in `compose.yaml`). Mount zonder allowlist leest
|
||||
niets; allowlist zonder mount resolvet niet. Er is bewust geen impliciete
|
||||
default, `/` al helemaal niet.
|
||||
2. Migratie `0017_source_convergence` (`alembic upgrade head`) voegt de
|
||||
convergentie-administratie toe aan `content.source_items`
|
||||
(`applied_fingerprint`, `applied_at`, `pending_job_id`, `attempts`,
|
||||
`last_failure_code`, `last_failure_retryable`), `pending` aan
|
||||
`source_sync_runs`, verbreedt `sync_state`/`outcome` naar 32 tekens, en
|
||||
vervangt de foreign key van `content.documents` door een samengestelde
|
||||
`(source_id, workspace_id, space_id)` met een bijbehorende unique key op
|
||||
`content.sources`.
|
||||
3. **Twee datawijzigingen in die migratie, geen schemawijzigingen:**
|
||||
(a) bestaande onthouden items worden als *applied* gebackfilld -- ze zijn
|
||||
geïngest onder het oude model, waarin een afgeronde discovery het enige
|
||||
completion-signaal was; (b) een bron die door `0016` over meerdere knowledge
|
||||
spaces heen mocht liggen wordt gesplitst naar per-space zusterbronnen
|
||||
(deterministisch afgeleid id) en de documenten daarvan worden omgehangen.
|
||||
4. Qdrant-punten van zulke *gesplitste* documenten dragen nog het oude
|
||||
`source_id`. Draai daarna een authoritative reconcile/rebuild van de actieve
|
||||
collectie, net als bij de 1.2.0-upgrade. Controleer vooraf of er iets te
|
||||
splitsen valt:
|
||||
|
||||
```sql
|
||||
SELECT DISTINCT d.source_id, d.workspace_id, d.space_id
|
||||
FROM content.documents AS d
|
||||
JOIN content.sources AS s ON s.id = d.source_id
|
||||
WHERE d.workspace_id <> s.workspace_id OR d.space_id <> s.space_id;
|
||||
```
|
||||
|
||||
Geen rijen = geen split en geen rebuild nodig voor deze stap.
|
||||
5. **Downgrade is niet symmetrisch.** De split wordt niet teruggedraaid (de
|
||||
zusterbronnen zijn echte bronnen geworden), en `awaiting_ingest` /
|
||||
`completed_with_failures` bestaan niet in het oude schema: die vallen bij een
|
||||
downgrade terug op `applying` respectievelijk `failed`, zodat een
|
||||
gedowngrade deployment "onaf of mislukt" leest in plaats van "geslaagd".
|
||||
6. Verwachte gedragsverandering na de uitrol: een sync meldt `awaiting_ingest`
|
||||
tot zijn child-`ingest_upload`-jobs teruggerapporteerd hebben, en
|
||||
`last_successful_sync_at` schuift alleen op bij een volledig geconvergeerde
|
||||
run. Een bron die eerder direct "Last sync ok" toonde, toont nu eerst
|
||||
"Indexing" -- dat is de correctie, geen regressie.
|
||||
|
||||
### OPERATIONS-ISOLATION (`0018`)
|
||||
|
||||
7. Migratie `0018_job_workspace_ownership` maakt eigenaarschap van een job een
|
||||
echte kolom (`jobs.jobs.workspace_id`, geïndexeerd) en voegt
|
||||
`content.source_items.last_failure_job_id` toe. De backfill is bewust
|
||||
fail-closed: alleen een `payload->>'workspace_id'` die zowel een geldige
|
||||
UUID is *als* een bestaande workspace aanwijst wordt overgenomen. Al het
|
||||
andere blijft `NULL` = *legacy*, en dat betekent onzichtbaar en
|
||||
onwijzigbaar voor elke workspace-gebonden principal; alleen een Platform
|
||||
Admin ziet zulke jobs nog. Verwachte gedragsverandering: een operator die
|
||||
vóór deze upgrade jobs van andere tenants zag, ziet nu alleen de eigen
|
||||
workspace. Controleer hoeveel rijen legacy blijven:
|
||||
|
||||
```sql
|
||||
SELECT count(*) FROM jobs.jobs WHERE workspace_id IS NULL;
|
||||
```
|
||||
|
||||
Die jobs zijn niet stuk; ze zijn alleen niet toewijsbaar. Laat ze aflopen of
|
||||
ruim ze op als Platform Admin.
|
||||
8. **`FILESYSTEM_SOURCE_MANAGE` is nieuw en ligt uitsluitend bij
|
||||
`PLATFORM_ADMIN`.** Een Folder- of Git-bron aanmaken *of wijzigen* vereist
|
||||
die permissie bovenop `SOURCE_MANAGE`. Workspace Admins en Space Managers
|
||||
die vóór deze upgrade filesystem-bronnen beheerden, kunnen dat niet meer;
|
||||
plan wie dat overneemt. De permissie en de `RAGCORE_SOURCE_ROOTS`-sandbox
|
||||
zijn onafhankelijke poorten: een pad buiten de allowlist wordt ook voor een
|
||||
Platform Admin geweigerd.
|
||||
|
||||
### RELEASE-CLEANUP (`0019`)
|
||||
|
||||
9. Migratie `0019_job_listing_index` voegt alleen een index toe
|
||||
(`ix_jobs_workspace_status_recent` op `(workspace_id, status, updated_at)`).
|
||||
Geen datawijziging, geen gedragsverandering buiten performance: het
|
||||
jobsoverzicht filtert vanaf deze release in SQL over de hele workspace in
|
||||
plaats van over een opgehaalde pagina, en dit is de index waarop die query
|
||||
draait. Op een grote `jobs.jobs` kost het aanmaken kort een write-lock;
|
||||
gebruik zo nodig `CREATE INDEX CONCURRENTLY` buiten Alembic om en markeer de
|
||||
migratie daarna als uitgevoerd.
|
||||
|
||||
## Upgrade naar 1.2.0
|
||||
|
||||
1. Migratie `0016_sources_lifecycle` (`alembic upgrade head`) maakt `content.sources`,
|
||||
`source_sync_runs`, `source_items`, voegt `documents.source_id` (NOT NULL, FK) toe en
|
||||
backfillt die uit `source_key` met dezelfde regel die de runtime gebruikt
|
||||
(UUID-vormige key = caller-bron; anders de ingebouwde *Uploads*-bron van de space).
|
||||
Voor iedere backfilled bron ontstaat een registry-record (kind `upload`).
|
||||
2. Qdrant-punten die vóór 1.2.0 zijn geïndexeerd dragen nog het oude synthetische
|
||||
`source_id` (uuid5 per document). Draai na de migratie een authoritative
|
||||
reconcile/rebuild van de actieve collectie (`IndexBuildService.reconcile`/`build`,
|
||||
beide gebruiken nu de canonical IndexPoint-mapping) zodat `source_ids`-filters en
|
||||
provenance ook voor bestaande content kloppen; tot die tijd matchen filters op die
|
||||
oude punten niet.
|
||||
3. Worker en app opnieuw uitrollen (nieuwe job-operation `sync_source`; nieuwe
|
||||
Control Plane-routes `/admin/sources`, `/admin/documents`, `/admin/system`).
|
||||
4. SDK-consumers: de citation-schema's kregen additieve optionele velden
|
||||
(`source_id`, `source_name`, `source_kind`, `locator`, `revision`, `display`).
|
||||
Reference in new issue
Block a user