homelab-codex-ws/kb/services/paperless.md
oskar 01db57ab82 fix(kb): przepiecie wszystkich odwolan wewnetrznych po migracji
126 plikow (md, yaml, sh, py) odwolywalo sie do sciezek sprzed migracji.

  15  markdown-linkow [..](..) -> policzona sciezka WZGLEDNA wobec pliku
      odsylajacego (wczesniej czesc z nich byla repo-root-relative i nie
      rozwiazywala sie z katalogu, w ktorym lezala)
 200  odwolan tekstowych (backticki, proza, yaml, importy w kodzie)
      -> nowa sciezka repo-root-relative, zgodnie z konwencja repo
   5  linkow rodzenstwa (gole nazwy plikow, np. "](DEPLOY.md)") — dzialaly
      tylko w starym katalogu; przeliczone recznie

Objete m.in.: CLAUDE.md (scripts/onboard/README.md -> kb/runbooks/
node-onboarding-tool.md, docs/backlog.md -> kb/phases/backlog.md),
README.md, .claude/skills/, 20 session logow, kod jobow.

Ostatnie 5 odwolan pochodzi z tresci wciagnietej rebasem z origin/master
(session log 2026-07-31, override node-agenta na SOLARII, dwie pozycje
backlogu) — wskazywaly na docs/incidents/, docs/kb/modules/ i
services/narty27/README.md sprzed migracji.

Dodany wzajemny link miedzy kb/services/control-plane.md (stub kodu)
a kb/subsystems/control-plane.md (opis, deprecated) — dwa dokumenty o tym
samym systemie, latwe do pomylenia.

Weryfikacja na 790 plikach: 0 odwolan do starych sciezek,
0 martwych linkow markdown. Lint OKF: 190/190 plikow ZGODNE.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 16:53:57 +02:00

99 lines
4.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
okf: "0.1"
type: service
visibility: private
status: active
updated: 2026-07-09
links:
- ../decisions/paperless-split-ocr.md
- ../runbooks/paperless-cutover.md
---
# Paperless-ngx (serwis, PIHA)
Serwis dokumentów filaru KB #2 (moduł 2, `kb/phases/kb-m2-paperless.md`):
UI + API + Postgres + Redis. Always-on na PIHA. Ciężki OCR wykonuje osobny worker
na SOLARIA (`services/paperless-worker/`, moduł 3) — tu zostaje tylko wolny
fallback (1 worker × 1 wątek).
**Paperless = archiwum REFERENCJA w hybrydzie kb-02** — jego storage jest źródłem
prawdy dla KB. Backup jest OBOWIĄZKOWY (patrz niżej), nie opcjonalny.
## Stack
| Kontener | Obraz | Rola |
|--------------------|------------------------------------------|-----------------------------|
| `paperless` | `ghcr.io/paperless-ngx/paperless-ngx:2.14` | UI+API+consumer+fallback-OCR (port 8000) |
| `paperless-db` | `postgres:16-alpine` | metadane (alias `db`) |
| `paperless-broker` | `redis:7-alpine` (AOF on) | kolejka zadań OCR (alias `broker`) |
Wszystkie porty bindowane na `LAN_BIND_IP` (192.168.31.5), nigdy 0.0.0.0:
- `8210` → web UI (za npm@PIHA, vhost `paper.kapala.org`, LAN/Tailscale only)
- `5434` → Postgres dla workera@SOLARIA (5433 zajęte przez kb-postgres); auth scram
- `6380` → Redis dla workera@SOLARIA (6379 zajęte przez agent-system-redis);
`requirepass` ustawione — `PAPERLESS_REDIS_PASSWORD` w `.env` po obu stronach
Obraz jest multi-arch (arm64 natywnie na Pi 5). Tag `2.14` MUSI być identyczny
z `services/paperless-worker/docker-compose.yml` — podbijać oba naraz.
## OIDC przez Forgejo
Mechanizm: `django-allauth` z providerem `openid_connect`
(`PAPERLESS_APPS=allauth.socialaccount.providers.openid_connect`), konfiguracja
providera w JSON-ie `PAPERLESS_SOCIALACCOUNT_PROVIDERS` (w `.env`, bo zawiera
client secret — patrz `env.example`).
Rejestracja w Forgejo (Settings → Applications, wzorzec jak Vikunja):
- Redirect URI: `https://paper.kapala.org/accounts/oidc/forgejo/login/callback/`
- Confidential client; scope `openid profile email`
`forgejo.kapala.org` jest przypięte przez `extra_hosts` do `192.168.31.5`
(npm na PIHA), żeby OIDC discovery szło po LAN — ta sama lekcja co w Vikunji.
Lokalny login zostaje na czas bootstrapu (konto `PAPERLESS_ADMIN_USER`);
po zweryfikowaniu OIDC ustawić `PAPERLESS_DISABLE_REGULAR_LOGIN=true` +
`PAPERLESS_REDIRECT_LOGIN_TO_SSO=true` (decyzja podjęta — zrobić PRZY DEPLOYU,
po potwierdzeniu logowania OIDC; TODO w compose).
## Storage i backup (WARUNEK BRZEGOWY hybrydy)
Dane na PIHA NVMe:
- `/opt/homelab/data/paperless/media` — **oryginały + zarchiwizowane PDF-y,
niezastępowalne**
- `/opt/homelab/data/paperless/data` — indeks wyszukiwania (Whoosh) +
klasyfikator — odtwarzalne (`document_index reindex`)
- `/opt/homelab/data/paperless/consume` — katalog zrzutu do ingestu
- `paperless_pgdata` (named volume) — metadane (tagi, korespondenci, daty)
- `paperless_redisdata` (named volume) — AOF kolejki zadań
### Backup (zatwierdzone — cel: SOLARIA, LAN; offsite później)
1. **Warstwa 1 — eksport spójny**: nocny cron na PIHA:
`docker exec paperless document_exporter ../export --delete -z`
wbudowane narzędzie; zrzuca oryginały + archiwa + `manifest.json`
(pełne metadane, odtwarzalne przez `document_importer` bez dumpa SQL).
Ląduje w `/opt/homelab/data/paperless/export`.
2. **Warstwa 2 — kopia poza hosta**: rsync/borg eksportu na SOLARIA
(2 TB NVMe, ta sama LAN) — SOLARIA sesyjna, więc pull przy starcie
lub push z retry. Wystarcza na start; VPS odpada (brak miejsca).
3. **Retencja (zatwierdzona)**: 7 dziennych + 4 tygodniowe + 6 miesięcznych.
4. Dump Postgresa nie jest konieczny do odtworzenia (manifest wystarcza),
ale tani — można dołożyć `pg_dump` do tej samej nocnej pętli.
5. **Future-note (poza zakresem tego etapu)**: offsite backup (np. restic →
chmura) poza SOLARIA-LAN, gdy pojawi się potrzeba/budżet.
Ten etap to tylko config + dokumentacja decyzji — cron/skrypt deployowy
(cron entry na PIHA, rsync/borg do SOLARII) powstaje przy deployu modułu 2,
nie tutaj.
## RAM na PIHA
Oczekiwany spoczynek: paperless ~400600 Mi (gunicorn + consumer + beat +
1 worker), postgres ~80 Mi, redis ~15 Mi. Limity twarde w
`hosts/piha/runtime/paperless/docker-compose.override.yml`. Warunek: moduł 0
(odchudzenie PIHA) wykonany — po nim ~3.8 Gi available.