feat(kb): configi Paperless/Nextcloud wg 9 decyzji — NC na PIHA, domeny kapala, Redis requirepass, backup SOLARIA, NC pin 34
Co zrobione: - Nextcloud host = PIHA (always-on dla aktywnego uzycia), owner_node + LAN_BIND_IP/TRUSTED_PROXIES w .env, README zaktualizowane - Redis brokera Paperlessa: requirepass, PAPERLESS_REDIS_PASSWORD w .env po obu stronach (PIHA + worker@SOLARIA), healthchecki z auth - Domeny potwierdzone: paper.kapala.org, cloud.kapala.org (Cloudflare DNS-only -> Tailscale PIHA, wildcard cert juz pokrywa) — udokumentowane, nic nie utworzone - Backup Paperlessa zatwierdzony: document_exporter + rsync/borg -> SOLARIA, retencja 7/4/6, offsite jako future-note - Nextcloud pin: 34-apache (zweryfikowany aktualny stable, endoflife.date) - Whoosh fallback-worker: zaakceptowane bez zmian - Porty/wylaczenie local login/sizing OCR-workera: przeniesione z "decyzji" na "TODO przy deployu" - DECYZJE-do-podjecia.md zaktualizowane: wszystko poza portami/loginem/ sizingiem przeniesione do "Rozstrzygniete" Tylko edycja configow w repo — nic nie zdeployowane, zadne kontenery nie byly ruszane, DNS/vhosty nie utworzone. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
e5ecefe2b7
commit
7e5577c58f
|
|
@ -1,32 +1,13 @@
|
|||
# Decyzje do podjęcia — filar dokumentów (moduły 2/3/4)
|
||||
|
||||
> Zbiorcza lista otwartych decyzji z przygotowania configów (2026-07-06,
|
||||
> branch `task/paperless-nextcloud-config`). Każda pozycja ma odpowiadający
|
||||
> komentarz `# TODO DECYZJA OSKARA:` w plikach serwisów. Configi są gotowe do
|
||||
> review — NIC nie zostało zdeployowane.
|
||||
> Zbiorcza lista decyzji z przygotowania configów (2026-07-06, branch
|
||||
> `task/paperless-nextcloud-config`; decyzje podjęte 2026-07-09, branch
|
||||
> `task/paperless-decyzje`). Configi są zaktualizowane wg decyzji poniżej —
|
||||
> NIC nie zostało zdeployowane, ten etap to tylko edycja plików w repo.
|
||||
|
||||
## 1. Host Nextclouda: PIHA czy SOLARIA
|
||||
## Otwarte — do zrobienia PRZY DEPLOYU (nie są to już decyzje, tylko kroki wykonawcze)
|
||||
|
||||
Jedyna duża decyzja architektoniczna. Moduł 4 i kb-02 skłaniają się ku
|
||||
**SOLARIA** (KB czyta własną kopię z archiwum na PIHA, więc dostępność
|
||||
Nextclouda nie warunkuje zapytań KB; koszt = sync dogania się po wybudzeniu).
|
||||
Tabela za/przeciw: `services/nextcloud/README.md`. Compose jest przenośne —
|
||||
decyzja ustawia tylko `owner_node` w `service.yaml` + `LAN_BIND_IP`
|
||||
i `TRUSTED_PROXIES` w `.env`. Wstępnie wpisane: SOLARIA.
|
||||
|
||||
## 2. Backup Paperlessa (warunek brzegowy hybrydy — musi być przed produkcyjnym użyciem)
|
||||
|
||||
Propozycja w `services/paperless/README.md`:
|
||||
|
||||
- nocny `document_exporter` (oryginały + archiwa + manifest metadanych,
|
||||
odtwarzalny bez dumpa SQL) do `/opt/homelab/data/paperless/export`,
|
||||
- kopia eksportu poza hosta: **rsync/borg → SOLARIA** (2 TB, ta sama LAN);
|
||||
otwarte: czy dokładać offsite (restic → chmura?),
|
||||
- retencja (propozycja): 7 dziennych + 4 tygodniowe + 6 miesięcznych.
|
||||
|
||||
Do zatwierdzenia: cel kopii (SOLARIA wystarczy? offsite?), retencja, narzędzie.
|
||||
|
||||
## 3. Porty (potwierdzić na żywym PIHA przed deployem)
|
||||
### 3. Porty (potwierdzić na żywym PIHA przed deployem)
|
||||
|
||||
Dobrane wg inwentaryzacji 2026-06-30 (snapshot! zweryfikować `ss -tlnp`):
|
||||
|
||||
|
|
@ -35,51 +16,20 @@ Dobrane wg inwentaryzacji 2026-06-30 (snapshot! zweryfikować `ss -tlnp`):
|
|||
| 8210 | paperless web | za npm@PIHA |
|
||||
| 5434 | paperless postgres | 5433 zajęte przez kb-postgres |
|
||||
| 6380 | paperless redis (broker dla workera) | 6379 zajęte przez agent-system-redis |
|
||||
| 8220 | nextcloud web | wolny i na PIHA, i na SOLARII |
|
||||
| 8220 | nextcloud web | teraz na PIHA (decyzja #1) — potwierdzić że nadal wolny |
|
||||
|
||||
Wszystkie bindowane na LAN IP (nie 0.0.0.0); ruch worker↔broker/DB/NFS po
|
||||
LAN 192.168.31.x, nie Tailscale.
|
||||
|
||||
## 4. Redis brokera bez auth na bindzie LAN
|
||||
|
||||
Broker (6380) i Postgres (5434) są wystawione na LAN IP PIHA dla workera na
|
||||
SOLARII. Postgres ma auth (scram); **Redis defaultowo nie ma**. Zaufany LAN
|
||||
domowy — akceptować, czy dołożyć `requirepass` (wtedy `PAPERLESS_REDIS`
|
||||
z hasłem wędruje do `.env` po obu stronach)?
|
||||
|
||||
## 5. Fallback-worker na PIHA a indeks Whoosh po NFS
|
||||
|
||||
Stockowy obraz na PIHA zawsze ma wbudowany worker (concurrency 1) — to
|
||||
naturalny fallback „domiela wolno". Ryzyko: gdy SOLARIA pracuje, **dwa hosty
|
||||
piszą do plikowego indeksu Whoosh** (PIHA lokalnie, SOLARIA po NFS) — znane
|
||||
upstreamowe objawy wyścigu („This writer is closed", korupcja indeksu).
|
||||
Indeks jest odtwarzalny (`document_index reindex`), oryginałom nic nie grozi.
|
||||
Decyzja: zaakceptować i obserwować (rekomendacja), czy od razu wymusić
|
||||
tryb „kolejka-czeka" (batch-OCR tylko w oknach pracy SOLARII)?
|
||||
Szczegóły: `services/paperless-worker/README.md`.
|
||||
|
||||
## 6. Domeny + wpisy DNS + vhosty npm
|
||||
|
||||
Założone w configach: `paper.kapala.org` (Paperless), `cloud.kapala.org`
|
||||
(Nextcloud) — moduły dopuszczały też `*.okit.pl`. Potwierdzić, potem:
|
||||
A-recordy (DNS Only) → PIHA + vhosty w npm@PIHA + rejestracja OAuth2 apps
|
||||
w Forgejo (redirect URIs w README serwisów zależą od domeny).
|
||||
|
||||
## 7. Wyłączenie lokalnego loginu w Paperless po weryfikacji OIDC
|
||||
### 7. Wyłączenie lokalnego loginu w Paperless po weryfikacji OIDC
|
||||
|
||||
Bootstrap idzie przez lokalnego admina (`PAPERLESS_ADMIN_USER`). Po
|
||||
potwierdzeniu działania Forgejo-OIDC: ustawić
|
||||
`PAPERLESS_DISABLE_REGULAR_LOGIN=true` + `PAPERLESS_REDIRECT_LOGIN_TO_SSO=true`?
|
||||
(Vikunja ma dziś oba tryby równolegle.)
|
||||
`PAPERLESS_DISABLE_REGULAR_LOGIN=true` + `PAPERLESS_REDIRECT_LOGIN_TO_SSO=true`
|
||||
(decyzja podjęta — wykonać dopiero po potwierdzonym logowaniu OIDC; Vikunja
|
||||
ma dziś oba tryby równolegle, ten sam wzorzec przejściowy).
|
||||
|
||||
## 8. Pin wersji Nextclouda
|
||||
|
||||
Compose ma ruchomy `nextcloud:stable-apache`; przy deployu przypiąć aktualny
|
||||
major (np. `:31-apache` — sprawdzić bieżący stable w dniu deployu). Nextcloud
|
||||
nie wspiera skoków o >1 wersję major, więc ruchomy tag na produkcji = ryzyko
|
||||
niekontrolowanego skoku.
|
||||
|
||||
## 9. Sizing workera OCR pod batch 70k załączników
|
||||
### 9. Sizing workera OCR pod batch 70k załączników
|
||||
|
||||
`WORKER_CONCURRENCY=4` × `PAPERLESS_THREADS_PER_WORKER=4` = ~16 wątków na
|
||||
24 rdzeniach SOLARII. Przed batchem 70k (moduł 5): zmierzyć na próbce i
|
||||
|
|
@ -87,7 +37,54 @@ zdecydować, czy podbić concurrency, czy zostawić zapas na ollama/AI.
|
|||
|
||||
---
|
||||
|
||||
## Rozstrzygnięte w tym przygotowaniu (dla porządku)
|
||||
## Rozstrzygnięte
|
||||
|
||||
- **1. Host Nextclouda: PIHA.** Oskar używa Nextclouda aktywnie (telefon,
|
||||
sync, rodzina) → musi być always-on; sesyjna dostępność SOLARII (sync
|
||||
dogania się dopiero po wybudzeniu) nie jest akceptowalna dla tego
|
||||
workloadu — mimo że moduł 4/kb-02 skłaniały się ku SOLARII (KB i tak
|
||||
czyta własną kopię z archiwum na PIHA, więc host Nextclouda nie warunkuje
|
||||
zapytań KB). `service.yaml`: `owner_node: piha`. `.env`: `LAN_BIND_IP`
|
||||
= 192.168.31.5, `TRUSTED_PROXIES` = docker bridge subnet (npm i nextcloud
|
||||
na tym samym hoście teraz). Uzasadnienie pełne: `services/nextcloud/README.md`.
|
||||
|
||||
- **2. Backup Paperlessa: SOLARIA (LAN), na start.** Nocny
|
||||
`document_exporter` (oryginały + archiwa + manifest, odtwarzalny bez
|
||||
dumpa SQL) → `/opt/homelab/data/paperless/export`, kopia poza hosta przez
|
||||
rsync/borg → SOLARIA (2 TB, ta sama LAN). Retencja: 7 dziennych +
|
||||
4 tygodniowe + 6 miesięcznych. Offsite (np. restic → chmura) zostaje jako
|
||||
future-note, poza zakresem tego etapu. Cron/skrypt deployowy powstaje przy
|
||||
deployu modułu 2, nie teraz. Szczegóły: `services/paperless/README.md`.
|
||||
|
||||
- **4. Redis brokera: `requirepass`.** Broker (6380) dostaje hasło —
|
||||
`PAPERLESS_REDIS_PASSWORD` w `.env` po obu stronach (paperless@PIHA,
|
||||
paperless-worker@SOLARIA), placeholder `CHANGEME` w `env.example`, realne
|
||||
hasło tylko w `.env` (gitignored). Healthchecki obu stron zaktualizowane
|
||||
o auth.
|
||||
|
||||
- **5. Fallback-worker na PIHA a indeks Whoosh po NFS: zaakceptować
|
||||
i obserwować.** Ryzyko wyścigu na plikowym indeksie Whoosh (PIHA lokalnie
|
||||
+ SOLARIA po NFS) świadomie zaakceptowane — indeks jest odtwarzalny
|
||||
(`document_index reindex`), oryginałom nic nie grozi. Bez zmian w
|
||||
configu; fallback-worker na PIHA zostaje. Szczegóły:
|
||||
`services/paperless-worker/README.md`.
|
||||
|
||||
- **6. Domeny: `kapala.org` (mesh, prywatne).** `paper.kapala.org`
|
||||
(Paperless), `cloud.kapala.org` (Nextcloud) — potwierdzone, `*.okit.pl`
|
||||
odrzucone. DNS i vhosty NIE utworzone w tym etapie — tylko
|
||||
udokumentowane w READMY serwisów (wzorzec: rekord A w Cloudflare →
|
||||
`100.108.208.3`, Tailscale PIHA, DNS Only, ten sam co
|
||||
`ha.kapala.org`/`immich.kapala.org` — `docs/sessions/2026-06-30-kapala-cloudflare-wildcard-mesh.md`;
|
||||
wildcard `*.kapala.org` już pokrywa obie subdomeny, nowe certy
|
||||
niepotrzebne). OAuth redirect URIs w Forgejo apps zapisane w READMY obu
|
||||
serwisów.
|
||||
|
||||
- **8. Pin wersji Nextclouda: `34-apache`.** Zweryfikowany aktualny stable
|
||||
na 2026-07-09 (wydany 2026-06-09, endoflife.date/nextcloud). Zamiast
|
||||
ruchomego `stable-apache`. Nextcloud wydaje nowy major co ~4 miesiące
|
||||
i nie wspiera przeskakiwania wersji przy upgrade — TODO przy deployu:
|
||||
potwierdzić bieżący stable tuż przed `docker compose up`, podbić tag
|
||||
jeśli wyszła nowsza wersja.
|
||||
|
||||
- **Split-host OCR-worker przez NFS: WYKONALNY** — wzorzec potwierdzony przez
|
||||
maintainerów paperless-ngx (nieoficjalnie wspierany): ten sam obraz,
|
||||
|
|
|
|||
|
|
@ -8,36 +8,43 @@ ingestu KB (moduł 5) przez WebDAV.
|
|||
do archiwum KB; Nextcloud NIE jest źródłem prawdy (inaczej niż Paperless).
|
||||
Backup „warto" (dane użytkownika), ale nie jest warunkiem brzegowym KB.
|
||||
|
||||
## TODO DECYZJA OSKARA: host (PIHA vs SOLARIA)
|
||||
## Decyzja: host = PIHA
|
||||
|
||||
Otwarte w kb-02 i module 4. Compose jest przenośne (ścieżki po konwencji
|
||||
`/opt/homelab/data`, bind IP i proxy w `.env`) — decyzja wybiera node
|
||||
i dwie wartości w `.env`.
|
||||
Moduł 4 skłaniał się ku SOLARIA (mocniejszy host, bez wpływu na KB — patrz
|
||||
niżej), ale Oskar zdecydował inaczej: **Nextcloud jest używany aktywnie**
|
||||
(telefon, sync, rodzina) — sesyjna dostępność SOLARII (sync dogania się
|
||||
dopiero po wybudzeniu hosta) nie jest akceptowalna dla tego workloadu.
|
||||
Nextcloud musi być **always-on**, więc ląduje na PIHA mimo ciaśniejszego
|
||||
RAM/CPU.
|
||||
|
||||
| | PIHA | SOLARIA |
|
||||
| | PIHA (wybrane) | SOLARIA |
|
||||
|---|---|---|
|
||||
| Dostępność | 24/7 (sync zawsze działa) | sesyjna — sync dogania się po wybudzeniu |
|
||||
| RAM/CPU | ciasno nawet po module 0 (Nextcloud+PHP ≈ 0.5–1 Gi+) | 62 Gi RAM, 24 rdzenie — bez znaczenia |
|
||||
| Storage | NVMe 477 G (dzielone z resztą) | NVMe 2 T |
|
||||
| Ingress | npm lokalnie | npm@PIHA proxuje po LAN do 192.168.31.70:8220 (npm proxuje na dowolny IP — bez przeszkód) |
|
||||
| Ingress | npm lokalnie (ten sam host) | npm@PIHA proxuje po LAN do 192.168.31.70:8220 |
|
||||
| Wpływ na KB | żaden — KB czyta własną kopię z archiwum na PIHA w obu wariantach | jw. |
|
||||
|
||||
Skłonność modułu 4: **SOLARIA** (dlatego `service.yaml` ma wstępnie
|
||||
`owner_node: solaria`, a `env.example` IP SOLARII). Koszt: przerwy w sync,
|
||||
gdy host śpi — do zaakceptowania, sync się dogoni.
|
||||
`service.yaml` ma `owner_node: piha`; `env.example` ma `LAN_BIND_IP` PIHA
|
||||
(192.168.31.5) i `TRUSTED_PROXIES` pod docker bridge (npm i nextcloud na
|
||||
tym samym hoście — patrz komentarz w `env.example`). Compose zostaje
|
||||
przenośne (ścieżki po konwencji `/opt/homelab/data`), gdyby host kiedyś
|
||||
się zmienił.
|
||||
|
||||
## Stack
|
||||
|
||||
| Kontener | Obraz | Rola |
|
||||
|------------------|-------------------------|---------------------------------------|
|
||||
| `nextcloud` | `nextcloud:stable-apache` | app + WebDAV (port 80 → host 8220 na LAN_BIND_IP) |
|
||||
| `nextcloud-cron` | `nextcloud:stable-apache` | joby w tle (`/cron.sh`, ten sam wolumen) |
|
||||
| `nextcloud` | `nextcloud:34-apache` | app + WebDAV (port 80 → host 8220 na LAN_BIND_IP) |
|
||||
| `nextcloud-cron` | `nextcloud:34-apache` | joby w tle (`/cron.sh`, ten sam wolumen) |
|
||||
| `nextcloud-db` | `postgres:16-alpine` | baza (bez portu na hoście) |
|
||||
| `nextcloud-redis`| `redis:7-alpine` | cache + file locking (bez portu, bez persystencji) |
|
||||
|
||||
TODO DECYZJA OSKARA: przy deployu przypiąć konkretną wersję major
|
||||
(np. `nextcloud:31-apache`) zamiast ruchomego `stable` — Nextcloud nie
|
||||
wspiera skoków o więcej niż jedną wersję major przy upgrade.
|
||||
Wersja przypięta na `34-apache` (aktualny stable na 2026-07-09, wydany
|
||||
2026-06-09 — zweryfikowane przez endoflife.date/nextcloud). Nextcloud
|
||||
wydaje nowy major co ~4 miesiące i nie wspiera przeskakiwania wersji przy
|
||||
upgrade — **TODO PRZY DEPLOYU**: potwierdzić bieżący stable tuż przed
|
||||
`docker compose up` i podbić tag, jeśli wyszła nowsza wersja.
|
||||
|
||||
## OIDC przez Forgejo (krok po-deployowy, occ)
|
||||
|
||||
|
|
@ -87,12 +94,17 @@ retencja krótsza (np. 7 dziennych + 4 tygodniowe).
|
|||
|
||||
## Cutover checklist (przy deployu — NIE teraz)
|
||||
|
||||
1. Decyzja hosta ↑ podjęta; `LAN_BIND_IP`/`TRUSTED_PROXIES` w `.env` pod nią.
|
||||
1. Host = PIHA (decyzja podjęta); `LAN_BIND_IP`/`TRUSTED_PROXIES` w `.env`
|
||||
już pod nią — `TRUSTED_PROXIES` doprecyzować przez `docker network
|
||||
inspect` na żywym hoście (patrz komentarz w `env.example`).
|
||||
2. Port wolny na żywym hoście: `ss -tlnp | grep 8220`.
|
||||
3. `mkdir -p /opt/homelab/data/nextcloud/{html,db}` na wybranym node.
|
||||
3. `mkdir -p /opt/homelab/data/nextcloud/{html,db}` na PIHA.
|
||||
4. `.env` z `env.example`.
|
||||
5. DNS `cloud.kapala.org` → PIHA (DNS Only) + vhost w npm@PIHA (HTTPS →
|
||||
`<LAN_BIND_IP>:8220`; jeśli host=SOLARIA, target = 192.168.31.70).
|
||||
5. DNS: rekord A `cloud.kapala.org` w Cloudflare → `100.108.208.3`
|
||||
(Tailscale PIHA, DNS Only) — ten sam wzorzec co `ha.kapala.org` /
|
||||
`immich.kapala.org` (`docs/sessions/2026-06-30-kapala-cloudflare-wildcard-mesh.md`);
|
||||
wildcard `*.kapala.org` już pokrywa tę subdomenę, nowy cert niepotrzebny.
|
||||
Plus vhost w npm@PIHA (HTTPS → `192.168.31.5:8220`, Advanced puste).
|
||||
6. `docker compose up -d`; pierwszy start instaluje NC (2–3 min),
|
||||
potem `./healthcheck.sh`.
|
||||
7. Kroki `occ` dla `user_oidc` (wyżej) + rejestracja appki w Forgejo +
|
||||
|
|
|
|||
|
|
@ -5,21 +5,23 @@
|
|||
# KOPIA in the kb-02 hybrid) — Nextcloud is NOT a source of truth, which
|
||||
# relaxes its backup and availability requirements vs paperless.
|
||||
#
|
||||
# TODO DECYZJA OSKARA: host — PIHA (always-on, ale ciasno) czy SOLARIA
|
||||
# (mocna, sesyjna; sync dogania sie po wybudzeniu)? Modul 4 sklania sie ku
|
||||
# SOLARIA. Compose jest przenosne: wszystkie sciezki po konwencji
|
||||
# /opt/homelab/data, bind IP i proxy z .env — decyzja wybiera tylko node
|
||||
# i wartosci w .env.
|
||||
# Host decided: PIHA (not SOLARIA) — Oskar uses Nextcloud actively (phone
|
||||
# sync, family), needs always-on availability; SOLARIA's session-only uptime
|
||||
# was not acceptable for this workload. See
|
||||
# docs/kb/modules/DECYZJE-do-podjecia.md #1 and README.md. Compose stays
|
||||
# portable: paths follow the /opt/homelab/data convention, bind IP and proxy
|
||||
# come from .env.
|
||||
#
|
||||
# EXPOSURE: LAN/Tailscale only przez npm@PIHA (cloud.kapala.org), zero public.
|
||||
# Jesli host=SOLARIA, npm@PIHA proxuje po LAN do 192.168.31.70:8220.
|
||||
# npm and nextcloud are both on PIHA — npm reaches it as a local container.
|
||||
services:
|
||||
nextcloud:
|
||||
# Multi-arch (arm64 + amd64) — runs on either candidate host.
|
||||
# TODO DECYZJA OSKARA: przy deployu przypiac konkretna wersje major
|
||||
# (np. nextcloud:31-apache) zamiast ruchomego "stable" — Nextcloud NIE
|
||||
# wspiera przeskakiwania wersji major przy upgrade.
|
||||
image: nextcloud:stable-apache
|
||||
# Pinned major: 34-apache was current stable as of 2026-07-09 (verified
|
||||
# via endoflife.date/nextcloud — released 2026-06-09). TODO AT DEPLOY:
|
||||
# Nextcloud ships a new major every ~4 months and does NOT support
|
||||
# skipping majors on upgrade — reconfirm the current stable major right
|
||||
# before `docker compose up` and bump the tag if one shipped since.
|
||||
image: nextcloud:34-apache
|
||||
container_name: nextcloud
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
|
|
@ -38,16 +40,19 @@ services:
|
|||
- POSTGRES_USER=nextcloud
|
||||
# Redis: PHP session locking + file locking cache.
|
||||
- REDIS_HOST=redis
|
||||
# TODO DECYZJA OSKARA: potwierdzic domene cloud.kapala.org + DNS + vhost npm.
|
||||
# Domain confirmed: cloud.kapala.org (mesh-only, *.kapala.org wildcard
|
||||
# cert already covers it). DNS + npm vhost are deploy-time steps, see
|
||||
# README Cutover checklist.
|
||||
- NEXTCLOUD_TRUSTED_DOMAINS=cloud.kapala.org
|
||||
# Behind npm@PIHA (TLS terminated there); without these Nextcloud
|
||||
# generates http:// links and login loops.
|
||||
- OVERWRITEPROTOCOL=https
|
||||
- OVERWRITEHOST=cloud.kapala.org
|
||||
- OVERWRITECLIURL=https://cloud.kapala.org
|
||||
# npm@PIHA as seen by this container: LAN IP of PIHA when Nextcloud
|
||||
# runs on SOLARIA; docker bridge subnet when it runs on PIHA itself —
|
||||
# hence configurable via .env.
|
||||
# npm@PIHA as seen by this container: since Nextcloud also runs on
|
||||
# PIHA, npm reaches it as a local container over the docker bridge
|
||||
# (not PIHA's LAN IP) — see TRUSTED_PROXIES in env.example. Kept
|
||||
# configurable via .env in case the host ever changes.
|
||||
- TRUSTED_PROXIES=${TRUSTED_PROXIES}
|
||||
- PHP_MEMORY_LIMIT=512M
|
||||
- PHP_UPLOAD_LIMIT=4G
|
||||
|
|
@ -59,8 +64,8 @@ services:
|
|||
ports:
|
||||
# Bind to the node's LAN IP only, never 0.0.0.0 — npm@PIHA is the sole
|
||||
# entry point (LAN/Tailscale). Port 8220 free on PIHA per the 2026-06-30
|
||||
# inventory; free on SOLARIA (nearly empty host).
|
||||
# TODO DECYZJA OSKARA: potwierdzic port na zywym hoscie: ss -tlnp | grep 8220
|
||||
# inventory.
|
||||
# TODO AT DEPLOY: reconfirm on the live host: ss -tlnp | grep 8220
|
||||
- "${LAN_BIND_IP}:8220:80"
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-fs", "--max-time", "5", "http://localhost:80/status.php"]
|
||||
|
|
|
|||
|
|
@ -1,16 +1,18 @@
|
|||
# Nextcloud secrets + host-local binds — copy to .env (gitignored) next to
|
||||
# docker-compose.yml and fill in real values. Never commit .env.
|
||||
|
||||
# LAN IP of the node Nextcloud lands on. The web port (8220) binds ONLY to
|
||||
# this interface — never 0.0.0.0.
|
||||
# TODO DECYZJA OSKARA: host! SOLARIA -> 192.168.31.70, PIHA -> 192.168.31.5.
|
||||
LAN_BIND_IP=192.168.31.70
|
||||
# LAN IP of the node Nextcloud lands on. Host decided: PIHA (see
|
||||
# docs/kb/modules/DECYZJE-do-podjecia.md #1). The web port (8220) binds ONLY
|
||||
# to this interface — never 0.0.0.0.
|
||||
LAN_BIND_IP=192.168.31.5
|
||||
|
||||
# Reverse proxy (npm@PIHA) as seen from THIS node's containers:
|
||||
# - Nextcloud on SOLARIA: npm connects over the LAN -> PIHA's LAN IP.
|
||||
# - Nextcloud on PIHA: npm is a local container -> use the docker bridge
|
||||
# subnet instead (e.g. 172.16.0.0/12), verify with docker network inspect.
|
||||
TRUSTED_PROXIES=192.168.31.5
|
||||
# Reverse proxy (npm@PIHA) as seen from THIS node's containers. Nextcloud
|
||||
# runs on PIHA (same host as npm) -> npm reaches it as a local container, so
|
||||
# the source IP is the docker bridge gateway, not PIHA's LAN IP. 172.16.0.0/12
|
||||
# covers Docker's default bridge allocation range; narrow it to the exact
|
||||
# /24 (docker network inspect <project>_default) once the stack is up on the
|
||||
# live host.
|
||||
TRUSTED_PROXIES=172.16.0.0/12
|
||||
|
||||
# Postgres password for the nextcloud DB (app reads the same var).
|
||||
POSTGRES_PASSWORD=change-me-very-strong
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
service:
|
||||
name: nextcloud
|
||||
# TODO DECYZJA OSKARA: owner_node — piha (always-on, ciasno) vs solaria
|
||||
# (mocna, sesyjna). Modul 4 / kb-02 sklaniaja sie ku SOLARIA: KB-kopia
|
||||
# dokumentow i tak lezy w archiwum na PIHA, wiec zapytania KB dzialaja bez
|
||||
# Nextclouda; sync z telefonu dogania sie po wybudzeniu hosta.
|
||||
owner_node: solaria
|
||||
# Decyzja Oskara: PIHA (nie SOLARIA). Uzasadnienie: Nextcloud jest uzywany
|
||||
# aktywnie (telefon, sync, rodzina) -> musi byc always-on, sesyjna
|
||||
# dostepnosc SOLARII nie jest akceptowalna dla tego workloadu (w
|
||||
# przeciwienstwie do KB-zapytan, ktore i tak czytaja wlasna kopie z
|
||||
# archiwum na PIHA niezaleznie od hosta Nextclouda). Patrz
|
||||
# docs/kb/modules/DECYZJE-do-podjecia.md #1 i README.md.
|
||||
owner_node: piha
|
||||
role: file-sync-drive # Drive replacement + WebDAV source for KB ingest (archiwum = KOPIA)
|
||||
exposure: private # LAN/Tailscale only via npm@PIHA (cloud.kapala.org); NO public ingress
|
||||
dependencies:
|
||||
|
|
|
|||
|
|
@ -26,8 +26,10 @@ services:
|
|||
- .env
|
||||
environment:
|
||||
# Broker + DB on PIHA over the fast LAN (NOT Tailscale) — same L2 as
|
||||
# the NFS mounts, transfer is not the bottleneck.
|
||||
- PAPERLESS_REDIS=redis://192.168.31.5:6380
|
||||
# the NFS mounts, transfer is not the bottleneck. Broker has
|
||||
# requirepass set — PAPERLESS_REDIS_PASSWORD in .env MUST equal the
|
||||
# value in services/paperless/.env on PIHA.
|
||||
- PAPERLESS_REDIS=redis://:${PAPERLESS_REDIS_PASSWORD}@192.168.31.5:6380
|
||||
- PAPERLESS_DBHOST=192.168.31.5
|
||||
- PAPERLESS_DBPORT=5434
|
||||
- PAPERLESS_DBNAME=paperless
|
||||
|
|
@ -41,8 +43,9 @@ services:
|
|||
- PAPERLESS_OCR_LANGUAGE=pol+eng
|
||||
# Threads used INSIDE a single OCR task; total load ~ concurrency ×
|
||||
# threads. 4×4=16 threads leaves headroom on 24 cores/32 threads.
|
||||
# TODO DECYZJA OSKARA: sizing pod batch 70k zalacznikow (moduł 5) —
|
||||
# podbic po probce (np. concurrency 8) czy zostawic zapas na ollama/AI?
|
||||
# TODO AT DEPLOY (module 5): measure on a sample before the 70k-attachment
|
||||
# batch — decide whether to raise concurrency (e.g. 8) or keep headroom
|
||||
# for ollama/AI workloads.
|
||||
- PAPERLESS_THREADS_PER_WORKER=4
|
||||
# MUST match paperless@PIHA — files on the NFS export carry numeric
|
||||
# UID/GID; a mismatch means this worker cannot read/write documents.
|
||||
|
|
|
|||
|
|
@ -9,8 +9,13 @@ PAPERLESS_SECRET_KEY=change-me-same-as-piha
|
|||
# MUST be identical to PAPERLESS_DBPASS in services/paperless/.env @ PIHA.
|
||||
PAPERLESS_DBPASS=change-me-same-as-piha
|
||||
|
||||
# MUST be identical to PAPERLESS_REDIS_PASSWORD in services/paperless/.env @
|
||||
# PIHA (broker requirepass) — a mismatch means this worker cannot reach the
|
||||
# queue.
|
||||
PAPERLESS_REDIS_PASSWORD=change-me-same-as-piha
|
||||
|
||||
# Parallel OCR tasks on SOLARIA (celery --concurrency). Total CPU load is
|
||||
# roughly WORKER_CONCURRENCY x PAPERLESS_THREADS_PER_WORKER (4x4=16 threads
|
||||
# default, on 24 cores / 32 threads).
|
||||
# TODO DECYZJA OSKARA: sizing pod batch 70k zalacznikow — zmierzyc na probce.
|
||||
# TODO AT DEPLOY (module 5): measure on a sample before the 70k-attachment batch.
|
||||
WORKER_CONCURRENCY=4
|
||||
|
|
|
|||
|
|
@ -29,4 +29,5 @@ service:
|
|||
env_vars:
|
||||
- PAPERLESS_SECRET_KEY # MUST equal the value on PIHA
|
||||
- PAPERLESS_DBPASS # MUST equal the value on PIHA
|
||||
- PAPERLESS_REDIS_PASSWORD # MUST equal the value on PIHA (broker requirepass)
|
||||
- WORKER_CONCURRENCY # optional, default 4 — parallel OCR tasks
|
||||
|
|
|
|||
|
|
@ -19,8 +19,9 @@ prawdy dla KB. Backup jest OBOWIĄZKOWY (patrz niżej), nie opcjonalny.
|
|||
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)
|
||||
- `6380` → Redis dla workera@SOLARIA (6379 zajęte przez agent-system-redis)
|
||||
- `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.
|
||||
|
|
@ -61,8 +62,9 @@ Rejestracja w Forgejo (Settings → Applications, wzorzec jak Vikunja):
|
|||
(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 rozważyć `PAPERLESS_DISABLE_REGULAR_LOGIN=true`
|
||||
(TODO DECYZJA OSKARA w compose).
|
||||
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)
|
||||
|
||||
|
|
@ -76,7 +78,7 @@ Dane na PIHA NVMe:
|
|||
- `paperless_pgdata` (named volume) — metadane (tagi, korespondenci, daty)
|
||||
- `paperless_redisdata` (named volume) — AOF kolejki zadań
|
||||
|
||||
### Propozycja backupu (TODO DECYZJA OSKARA — zatwierdzić przed deployem)
|
||||
### 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` —
|
||||
|
|
@ -85,11 +87,16 @@ Dane na PIHA NVMe:
|
|||
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. Alternatywa/uzupełnienie: offsite (restic → chmura?).
|
||||
VPS odpada (brak miejsca).
|
||||
3. **Retencja (propozycja)**: 7 dziennych + 4 tygodniowe + 6 miesięcznych.
|
||||
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
|
||||
|
||||
|
|
@ -104,7 +111,11 @@ Oczekiwany spoczynek: paperless ~400–600 Mi (gunicorn + consumer + beat +
|
|||
2. Porty wolne na żywym hoście: `ss -tlnp | grep -E '8210|5434|6380'`.
|
||||
3. `mkdir -p /opt/homelab/data/paperless/{data,media,consume,export}` na PIHA.
|
||||
4. `.env` z `env.example` (sekrety + rejestracja OAuth2 w Forgejo).
|
||||
5. DNS `paper.kapala.org` → PIHA (DNS Only) + vhost w npm@PIHA (HTTPS → 192.168.31.5:8210).
|
||||
5. DNS: rekord A `paper.kapala.org` w Cloudflare → `100.108.208.3`
|
||||
(Tailscale PIHA, DNS Only) — ten sam wzorzec co `ha.kapala.org` /
|
||||
`immich.kapala.org` (`docs/sessions/2026-06-30-kapala-cloudflare-wildcard-mesh.md`);
|
||||
wildcard `*.kapala.org` już pokrywa tę subdomenę, nowy cert niepotrzebny.
|
||||
Plus vhost w npm@PIHA (HTTPS → `192.168.31.5:8210`, Advanced puste).
|
||||
6. `docker compose up -d` + `./healthcheck.sh` + testowy login OIDC.
|
||||
7. Export NFS dla workera (patrz `services/paperless-worker/README.md`) —
|
||||
dopiero przy module 3.
|
||||
|
|
|
|||
|
|
@ -33,11 +33,14 @@ services:
|
|||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
# TODO DECYZJA OSKARA: potwierdzic domene paper.kapala.org (vs paper.okit.pl)
|
||||
# + wpis DNS (A -> LAN/Tailscale, DNS Only) + vhost w npm@PIHA.
|
||||
# Domain confirmed: paper.kapala.org (mesh-only, *.kapala.org wildcard
|
||||
# cert already covers it — no new cert needed). DNS + npm vhost are
|
||||
# deploy-time steps, see README Cutover checklist.
|
||||
- PAPERLESS_URL=https://paper.kapala.org
|
||||
- PAPERLESS_TIME_ZONE=Europe/Warsaw
|
||||
- PAPERLESS_REDIS=redis://broker:6379
|
||||
# Password-protected broker (requirepass) — see PAPERLESS_REDIS_PASSWORD
|
||||
# in .env. MUST match the broker's --requirepass value below.
|
||||
- PAPERLESS_REDIS=redis://:${PAPERLESS_REDIS_PASSWORD}@broker:6379
|
||||
- PAPERLESS_DBHOST=db
|
||||
- PAPERLESS_DBNAME=paperless
|
||||
- PAPERLESS_DBUSER=paperless
|
||||
|
|
@ -60,8 +63,9 @@ services:
|
|||
# First Forgejo login auto-creates the matching Paperless account.
|
||||
- PAPERLESS_SOCIALACCOUNT_ALLOW_SIGNUPS=true
|
||||
# No self-service local signups; local admin login stays for bootstrap.
|
||||
# TODO DECYZJA OSKARA: po zweryfikowaniu logowania OIDC ustawic
|
||||
# PAPERLESS_DISABLE_REGULAR_LOGIN=true + PAPERLESS_REDIRECT_LOGIN_TO_SSO=true?
|
||||
# TODO AT DEPLOY: after OIDC login is verified working, set
|
||||
# PAPERLESS_DISABLE_REGULAR_LOGIN=true + PAPERLESS_REDIRECT_LOGIN_TO_SSO=true
|
||||
# (decision already made — Vikunja runs both modes in parallel today too).
|
||||
- PAPERLESS_ACCOUNT_ALLOW_SIGNUPS=false
|
||||
volumes:
|
||||
# Bind mounts under /opt/homelab/data (runtime path convention). These
|
||||
|
|
@ -74,8 +78,8 @@ services:
|
|||
- /opt/homelab/data/paperless/export:/usr/src/paperless/export
|
||||
ports:
|
||||
# LAN-only bind; npm@PIHA proxies paper.kapala.org -> 192.168.31.5:8210.
|
||||
# TODO DECYZJA OSKARA: port 8210 wolny wg inwentaryzacji 2026-06-30 —
|
||||
# potwierdzic na zywym hoscie przed deployem: ss -tlnp | grep 8210
|
||||
# TODO AT DEPLOY: port 8210 free per the 2026-06-30 inventory —
|
||||
# reconfirm on the live host: ss -tlnp | grep 8210
|
||||
- "${LAN_BIND_IP}:8210:8000"
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-fs", "-S", "--max-time", "2", "http://localhost:8000"]
|
||||
|
|
@ -115,18 +119,22 @@ services:
|
|||
# (up to the 70k-attachment backlog) live only in this Redis. Without AOF a
|
||||
# broker restart would silently drop the queue — violating the "zero lost
|
||||
# tasks" criterion of module 3. Do NOT set maxmemory/eviction here.
|
||||
command: redis-server --appendonly yes
|
||||
# requirepass: broker is bound to the LAN interface (trusted home network,
|
||||
# but still reachable by anything on that LAN) — password auth decided
|
||||
# over relying on the bind alone. Same value MUST be set as
|
||||
# PAPERLESS_REDIS_PASSWORD in .env on both PIHA (this file) and
|
||||
# paperless-worker@SOLARIA.
|
||||
command: redis-server --appendonly yes --requirepass ${PAPERLESS_REDIS_PASSWORD}
|
||||
volumes:
|
||||
- paperless_redisdata:/data
|
||||
ports:
|
||||
# LAN-only bind for paperless-worker@SOLARIA. 6379 is taken by
|
||||
# agent-system-redis.
|
||||
# TODO DECYZJA OSKARA: Redis bez auth na bindzie LAN (zaufana siec
|
||||
# domowa) — akceptowalne, czy dolozyc requirepass? (wtedy PAPERLESS_REDIS
|
||||
# z haslem przenosi sie do .env po obu stronach)
|
||||
# TODO AT DEPLOY: port 6380 free per the 2026-06-30 inventory —
|
||||
# reconfirm on the live host: ss -tlnp | grep 6380
|
||||
- "${LAN_BIND_IP}:6380:6379"
|
||||
healthcheck:
|
||||
test: ["CMD", "redis-cli", "ping"]
|
||||
test: ["CMD", "redis-cli", "-a", "${PAPERLESS_REDIS_PASSWORD}", "--no-auth-warning", "ping"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
|
|
|||
|
|
@ -16,12 +16,17 @@ PAPERLESS_SECRET_KEY=change-me-long-random-string
|
|||
POSTGRES_PASSWORD=change-me-very-strong
|
||||
PAPERLESS_DBPASS=change-me-very-strong
|
||||
|
||||
# Redis broker password (requirepass). MUST be identical in
|
||||
# services/paperless-worker/.env on SOLARIA — a mismatch means the worker
|
||||
# cannot reach the queue.
|
||||
PAPERLESS_REDIS_PASSWORD=CHANGEME
|
||||
|
||||
# OIDC provider config (django-allauth openid_connect) — single-line JSON.
|
||||
# Lives in .env because it embeds the Forgejo OAuth2 client secret.
|
||||
# Register the app in Forgejo: Settings > Applications >
|
||||
# Domain confirmed: paper.kapala.org. Register the app in Forgejo:
|
||||
# Settings > Applications >
|
||||
# Redirect URI: https://paper.kapala.org/accounts/oidc/forgejo/login/callback/
|
||||
# then paste client_id + secret below.
|
||||
# TODO DECYZJA OSKARA: potwierdzic domene paper.kapala.org przed rejestracja w Forgejo.
|
||||
PAPERLESS_SOCIALACCOUNT_PROVIDERS={"openid_connect":{"SCOPE":["openid","profile","email"],"OAUTH_PKCE_ENABLED":true,"APPS":[{"provider_id":"forgejo","name":"Forgejo","client_id":"CHANGE-ME-CLIENT-ID","secret":"CHANGE-ME-CLIENT-SECRET","settings":{"server_url":"https://forgejo.kapala.org/.well-known/openid-configuration"}}]}}
|
||||
|
||||
# Bootstrap admin (local login) — used until OIDC is verified, then consider
|
||||
|
|
|
|||
|
|
@ -24,8 +24,9 @@ if ! curl -sfL --max-time 10 "http://${BIND_IP}:8210/" > /dev/null; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
# Redis broker must answer on the LAN bind (the SOLARIA worker depends on it)
|
||||
if ! docker exec paperless-broker redis-cli -h "${BIND_IP}" -p 6380 ping | grep -q PONG; then
|
||||
# Redis broker must answer on the LAN bind (the SOLARIA worker depends on it).
|
||||
# requirepass is set — auth with PAPERLESS_REDIS_PASSWORD from .env.
|
||||
if ! docker exec paperless-broker redis-cli -h "${BIND_IP}" -p 6380 -a "${PAPERLESS_REDIS_PASSWORD}" --no-auth-warning ping | grep -q PONG; then
|
||||
echo "[FAIL] redis broker is not answering on ${BIND_IP}:6380 (worker@SOLARIA cannot connect)"
|
||||
exit 1
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -45,4 +45,5 @@ service:
|
|||
- PAPERLESS_SECRET_KEY
|
||||
- PAPERLESS_DBPASS
|
||||
- POSTGRES_PASSWORD # must equal PAPERLESS_DBPASS
|
||||
- PAPERLESS_REDIS_PASSWORD # broker requirepass; must equal paperless-worker@SOLARIA
|
||||
- PAPERLESS_SOCIALACCOUNT_PROVIDERS # OIDC provider JSON incl. Forgejo client secret
|
||||
|
|
|
|||
Loading…
Reference in a new issue