homelab-codex-ws/kb/audits/piha-slim-2026-07-02.md
oskar 6dffa5c565 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:21:16 +02:00

241 lines
17 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: audit
visibility: private
status: active
updated: 2026-07-02
as_of: 2026-07-02
links: []
---
# Audyt odchudzania PIHA — 2026-07-02
> Faza 1 (READ-ONLY) modulu 0 filaru dokumentow (`kb/phases/kb-m0-piha-slim.md`).
> Zadna akcja nie zostala wykonana — wylacznie `docker stats/inspect/logs`, `ss`, `curl` (odczyt).
> Stan w momencie audytu: **RAM 7.9Gi total, 5.0Gi used, 2.9Gi available; swap 4Gi total, 2.0Gi uzyty.**
> 41 kontenerow Up (inwentaryzacja 2026-06-30 liczyla 40; wszystkie nadal biega).
>
> **AKTUALIZACJA 2026-07-02 (FAZA 2):** czesc rekomendacji zostala skorygowana po review
> Oskara i wykonana — patrz sekcja [Korekta po review + egzekucja](#korekta-po-review--egzekucja-2026-07-02)
> na koncu dokumentu. W skrocie: ES+diskover UBITE; llm-gateway ZOSTAJE (wlasny kod);
> immich ZOSTAJE NA PIHA na stale.
## Podsumowanie: ile RAM da sie zwolnic
| Kategoria | Kontenery | RAM (suma rezydentna) |
|---|---|---|
| **BEZPIECZNY USUN** | elasticsearch, diskover, llm-gateway | **~917 MiB** |
| **PRZENIES** (kandydat: SOLARIA) | immich (4 kontenery) | **~620 MiB** |
| Razem potencjal | 7 kontenerow | **~1.54 GiB** |
Po samym "BEZPIECZNY USUN": available rosnie z ~2.9Gi do **~3.8Gi** — kryterium modulu
(>= 1.5Gi available stabilnie) spelnione z duzym zapasem jeszcze przed migracja immich.
Dodatkowo elasticsearch (JVM, heap 512m ale RSS ~900Mi) jest glownym podejrzanym o
zajety swap — po jego usunieciu presja na swap powinna realnie spasc.
Uwaga metodyczna: `docker stats` pokazuje pamiec rezydentna (bez stron w swapie), wiec
realny zysk moze byc *wiekszy* niz suma powyzej.
## Kluczowe ustalenia (odpowiedzi na pytania modulu)
1. **elasticsearch (895Mi) sluzy WYLACZNIE diskoverowi** — nie wikijs.
Dowody:
- siec `diskover_default` zawiera tylko `elasticsearch` + `diskover`; wikijs siedzi
w `wikijs_default` ze swoim postgresem (`DB_TYPE=postgres`, brak zmiennych ES);
- jedyny indeks uzytkowy: `diskover-pimedia`, 133 862 dok., **21.8 MB**, utworzony
**2025-10-15** — od ~8.5 miesiaca zero reindeksacji (index_total=43 to tylko geoip);
- 92 zapytania search w 5 dni uptime (szum UI/healthcheck), zero polaczen
established na :9200 w trakcie audytu; homepage nie ma widgetu diskover/ES.
2. **diskover to martwy indekser**: zaindeksowal raz w pazdzierniku 2025, logi puste od
>=24h, web-UI nieuzywane. Trzyma przy zyciu ES wart ~900Mi RAM dla 22MB danych.
3. **llm-gateway nie ma zadnego konsumenta**: jedyny ruch w logach to Prometheus
odpytujacy `/v1/metrics` i dostajacy **404** (target nazwany `watchtower` w prom —
oczekuje watchtowera na :8080, a port zajal llm-gateway). Zero polaczen na :8080.
4. **Na PIHA dziala host-owy mosquitto (systemd, port 1883)** — inwentaryzacja
2026-06-30 mowila "na PIHA nie ma mosquitto" (prawda tylko dla Dockera). To
KRYTYCZNA zaleznosc: zigbee2mqtt (`mqtt://192.168.31.5:1883`), owntracks-recorder,
mqtt-exporter i RPi-Reporter-MQTT2HA-Daemon lacza sie do niego. Nie ruszac.
5. **forgejo na PIHA to origin repo GitOps** (`ssh://git@100.108.208.3:222/...` = PIHA
Tailscale, port 222) + provider OIDC dla vikunji. Absolutnie ZOSTAW.
6. **prom 342% CPU** z pierwszego pomiaru to byl chwilowy burst — powtorny pomiar:
1.87% CPU. Bez alarmu, ale 513Mi RAM to kandydat do tuningu retencji (osobno).
## Tabela glowna: shadow-kontenery
RAM = rezydentny z `docker stats` w trakcie audytu. Kontenery GitOps (ha-diag-agent,
node-agent, brain-watchdog, vikunja, vikunja-db, kb-postgres, stability-agent) pominiete
zgodnie z zakresem.
| Kontener | RAM | Kto uzywa | Zywy? | Kategoria | Uzasadnienie | Zysk |
|---|---|---|---|---|---|---|
| **elasticsearch** | 895Mi | tylko diskover (siec `diskover_default`) | Up, ale indeks z 2025-10-15; brak polaczen na :9200 | **BEZPIECZNY USUN** | 900Mi RAM dla 22MB martwego indeksu; wikijs uzywa postgresa, nie ES | **895Mi** |
| **diskover** | 7Mi | nikt (web-UI :9999 bez ruchu, logi puste) | martwy funkcjonalnie | **BEZPIECZNY USUN** | jednorazowy indekser, ostatni bieg 8.5 mies. temu; usuwac RAZEM z ES | 7Mi |
| **llm-gateway** | 15Mi | nikt (tylko 404 od prom) | Up, zero realnego ruchu | **BEZPIECZNY USUN** | brak konsumenta; przy okazji zwalnia port 8080 i usuwa falszywy target prom | 15Mi |
| immich_server | 416Mi | uzytkownik (vhosty immich.okit.pl, foty.kapala.org; widget homepage) | Up, tylko logi version-check w 48h | **PRZENIES** | foto+ML nie musi byc na always-on Pi; SOLARIA ma GPU i RAM; wymaga planu migracji danych (biblioteka na NVMe /home) | 416Mi |
| immich_postgres | 165Mi | immich | Up | **PRZENIES** | razem z immich | 165Mi |
| immich_machine_learning | 30Mi | immich | Up | **PRZENIES** | ML na arm64 CPU to marnotrawstwo; na SOLARIA zyska GPU | 30Mi |
| immich_redis | 10Mi | immich | Up | **PRZENIES** | razem z immich | 10Mi |
| forgejo_dind | 36Mi | forgejo CI (runner) | Up, logi puste >=48h | **DECYZJA OSKARA** | jesli CI na PIHA nieuzywane → stop (36Mi); jesli uzywane sporadycznie → zostaje | (36Mi) |
| code-server | 15Mi | vhost code-server.okit.pl, link w homepage | Up, logi puste, 0 polaczen na :8443 | **DECYZJA OSKARA** | nieuzywany od >=24h, ale zysk trywialny; kwestia higieny, nie RAM | (15Mi) |
| portainer | 22Mi | vhost portainer.okit.pl | Up, idle | **DECYZJA OSKARA** | UI do zarzadzania kontenerami — koliduje filozoficznie z GitOps, ale bywa przydatny awaryjnie | (22Mi) |
| mqtt-exporter-mqtt-exporter-1 | 22Mi | prom (target `mqtt-exporter` up) | Up, ale DEGRADED: "metric limit reached (2000)" w logach | **DECYZJA OSKARA** | duplikat: na hoscie biega DRUGI exporter (`/opt/mqtt-exporter/exporter.py`, root, od cze27); ktorys z dwoch jest zbedny — wymaga rozstrzygniecia ktory faktycznie serwuje :9000 (potrzebny root) | (22Mi) |
| **forgejo** | 173Mi | **origin repo GitOps** (SATURN commituje tu), vikunja OIDC, vhost | Up, aktywny | **ZOSTAW** | krytyczna infrastruktura; naprawic owner_node (rozjazd #2) | — |
| forgejo-db-1 | 31Mi | forgejo | Up | **ZOSTAW** | baza forgejo | — |
| homeassistant5 | 626Mi | ha-diag-agent (target localhost:8123), vhosty ha.kapala.org / ha-embed | Up, aktywny | **ZOSTAW** | HA "ken"; dodac do repo (rozjazd #5) | — |
| nginxproxymanager-app-1 | 234Mi | **32 vhosty** okit.pl/kapala.org (wiki, immich, vault, grafana, forgejo, ha, ...) | Up, aktywny | **ZOSTAW** | glowny reverse proxy LAN+public na PIHA; konsolidacja z NPM@VPS = osobny temat (rozjazd #4) | — |
| zigbee2mqtt | 117Mi | HA (via mosquitto hostowy), vhost zigbee.okit.pl | Up, aktywny | **ZOSTAW** | service.yaml owner=piha ✓; naprawic topology (rozjazd #15) | — |
| prom | 513Mi | grafana (datasource), vhost prometheus.okit.pl | Up, 23 targety | **ZOSTAW** | rdzen monitoringu = rola PIHA; osobno: tuning retencji moze zbic RAM | — |
| grafana | 183Mi | uzytkownik (vhost, homepage), zrodlo: prom | Up | **ZOSTAW** | rdzen monitoringu | — |
| node-exporter | 22Mi | prom (target up) | Up | **ZOSTAW** | metryki hosta | — |
| pihole-exporter | 13Mi | prom (target up) | Up | **ZOSTAW** | scrape'owany | — |
| fail2ban-prometheus-exporter | 14Mi | prom (target up) | Up | **ZOSTAW** | scrape'owany | — |
| owntracks-prometheus-exporter | 16Mi | prom (target up) | Up | **ZOSTAW** | scrape'owany; to on polluje `/api/0/last` recordera | — |
| owntracks-recorder | 3Mi | exporter + frontend + mosquitto hostowy | Up, aktywnie odpytywany | **ZOSTAW** | dziala, kosztuje grosze | — |
| own-tracks-frontend | 3Mi | uzytkownik (vhost owntracks-frontend.okit.pl) | Up | **ZOSTAW** | 3Mi | — |
| vaultwarden | 18Mi | uzytkownik (vault.okit.pl) | Up (healthy) | **ZOSTAW** | menedzer hasel — krytyczny, tani | — |
| wikijs-wiki-1 | 73Mi | uzytkownik (wiki.okit.pl, homepage) | Up, tylko joby konserwacyjne w logach | **ZOSTAW** | wiki z publicznym vhostem; ruch odczytu nie loguje sie na poziomie info — brak dowodu smierci; **nie zalezy od ES** | — |
| wikijs-db-1 | 14Mi | wikijs | Up | **ZOSTAW** | baza wiki | — |
| audiobookshelf | 27Mi | uzytkownik (audiobooks.okit.pl) | Up | **ZOSTAW** | apka uzytkowa, tania | — |
| actual-server | 19Mi | uzytkownik (budget.okit.pl) | Up | **ZOSTAW** | budzet domowy, tani | — |
| homepage | 90Mi | uzytkownik (home.okit.pl) | Up (healthy) | **ZOSTAW** | dashboard-agregator | — |
| agent-system-webui | 8Mi | telegram-bot (`CONTROL_PLANE_URL=http://webui:8080`), port 18180 | Up | **ZOSTAW** | aktywny flow zatwierdzania akcji na PIHA | — |
| agent-system-telegram-bot | 26Mi | operator (Telegram) | Up, polling co 10s | **ZOSTAW** | to JEST kanal human-in-the-loop z architektury | — |
| agent-system-runtime-materializer | 22Mi | zapisuje `/opt/homelab/world` co 10s | Up, aktywny | **ZOSTAW** | zywy komponent agent-systemu | — |
| agent-system-redis | 10Mi | runtime-materializer (`REDIS_HOST=redis`), webui | Up | **ZOSTAW** | broker agent-systemu | — |
Nota o "shadow": agent-system-\*, forgejo, zigbee2mqtt i npm MAJA definicje w
`services/` w repo (kompozycje na PIHA startowane z `/home/oskar/homelab-codex-ws/services/...`
na samym PIHA), ale brakuje ich w `hosts/piha/services.yaml` — to luka deklaracyjna,
nie brak definicji. Reszta shadow-stackow zyje w `/home/pi/<nazwa>/` i `/opt/`.
## Rekomendacje w kolejnosci (zysk / ryzyko)
1. **Stop + disable: elasticsearch + diskover** (razem, to jeden stack `/home/pi/diskover`)
— zysk ~902Mi, ryzyko ~zero (jedyny konsument ES to diskover; indeks martwy od
pazdziernika 2025). Przed usunieciem obrazow/wolumenow: zostawic wolumen ES na
tydzien "na wszelki wypadek" (22MB danych; ewentualnie `elasticdump` do pliku).
2. ~~**Stop: llm-gateway** (`/opt/llm-gateway`) — zysk 15Mi + porzadek: znika port 8080
i wiecznie failujacy target `watchtower` w prom (albo poprawic prom config w kroku 5).~~
**WYCOFANE po review** — llm-gateway to wlasny kod Oskara, czesc systemu agentowego;
zostaje. Patrz sekcja korekty.
3. ~~**Decyzja: migracja immich na SOLARIA** — zysk ~620Mi na PIHA. Wymaga osobnego planu
migracji (biblioteka zdjec + postgres pgvecto-rs; reguly repo: "data paths stay in
place at cutover" → to pelnoprawny projekt, nie quick-win). ML na GPU SOLARII to
dodatkowy bonus jakosciowy.~~
**WYCOFANE po review** — immich musi byc dostepny 24/7, a SOLARIA jest wlaczana
sesyjnie. Immich zostaje na PIHA na stale.
4. **Decyzja: forgejo_dind** — jesli CI nieaktywne: stop (36Mi). Sprawdzic w UI forgejo
czy sa zarejestrowane runnery/ostatnie buildy.
5. **Porzadki po-usuwaniu (osobny task, poza faza 1):** wyczyscic target `watchtower`
z konfiguracji prom; rozstrzygnac duplikat mqtt-exporter (host vs kontener — kontener
ma przepelniony limit 2000 metryk, wiec i tak wymaga naprawy); rozwazyc tuning
retencji prom (513Mi).
6. **GitOps-yzacja tego co zostaje** (kryterium modulu): dopisac do
`hosts/piha/services.yaml` co najmniej: forgejo(+db,+dind jesli zostaje),
homeassistant, npm-piha, agent-system, homepage, monitoring-stack — zgodnie z
backlogiem rozjazdow #2/#4/#5/#23.
## Ryzyka i zaleznosci (czego NIE ruszac i dlaczego)
- **forgejo (+forgejo-db-1)** — origin GitOps repo i OIDC vikunji. Awaria = brak
push/pull dla calej floty. Nie ruszac bez planu.
- **Host-owy mosquitto (systemd, :1883)** — POZA Dockerem, latwo przeoczyc. Zaleza od
niego: zigbee2mqtt, owntracks-recorder, mqtt-exporter, RPi-Reporter, posrednio HA.
Zadna akcja kontenerowa go nie dotyczy, ale przy porzadkach hostowych: nie dotykac.
(Korekta do inwentaryzacji 2026-06-30: mosquitto NA PIHA istnieje — host-level.)
- **nginxproxymanager-app-1** — pojedynczy punkt wejscia dla ~32 vhostow. Restart =
chwilowa niedostepnosc wszystkiego z okit.pl. Konsolidacje z VPS-owym NPM planowac
osobno.
- **homeassistant5** — target ha-diag-agenta; jego restart wygeneruje eventy/akcje w
agent-systemie (planowane restarty robic swiadomie).
- **agent-system-\*** — zywy human-in-the-loop (Telegram). Nie mylic ze "starymi
agent-system kontenerami" z backlogu — sa aktywne co 10s.
- **wikijs** — brak dowodu uzycia w logach, ale to charakter poziomu logowania, nie
dowod smierci; ma publiczny vhost. Ewentualna emerytura wiki = decyzja produktowa
Oskara, nie porzadkowa.
- **elasticsearch: kolejnosc** — najpierw stop diskover, potem ES (nie odwrotnie), zeby
diskover nie zaczal krzyczec do martwego ES. W praktyce: `docker-compose down` calego
stacka `/home/pi/diskover` za jednym zamachem (FAZA 2, po zgodzie).
## Obserwacje poboczne (poza zakresem, do backlogu)
- prom ma 6 targetow **down** (node-exportery: .11, .60, .40, .6, .8 oraz haos-glances) —
szum w monitoringu, warte przegladu.
- Kontenerowy mqtt-exporter jest funkcjonalnie zdegradowany (limit 2000 metryk
osiagniety — czesc sensorow NIE jest eksportowana do prom od dluzszego czasu).
- Na hoscie biegaja tez procesy poza Dockerem: RPi-Reporter-MQTT2HA-Daemon,
`/opt/mqtt-exporter/exporter.py` (root) — host-level shadow, nieobjete inwentaryzacja.
## Korekta po review + egzekucja (2026-07-02)
FAZA 2 wykonana po review Oskara. Decyzje i korekty wzgledem fazy 1:
### Korekta 1: llm-gateway ZOSTAJE (wlasny kod, system agentowy)
Audyt oznaczyl llm-gateway jako "BEZPIECZNY USUN — zero konsumentow" na podstawie
chwilowego braku ruchu. **Za slabe kryterium dla wlasnego serwisu** — kontener zostaje.
Udokumentowana rola (odczyt `/opt/llm-gateway` na PIHA, 2026-07-02):
- **Co to jest**: wlasny FastAPI-router LLM Oskara (Python 3.12, fastapi+httpx+uvicorn),
~90 linii w `app/main.py`. Compose project `llm-gateway`, katalog `/opt/llm-gateway`
(root, pliki z 2026-04-20/21), port `8080:8080`, `restart: unless-stopped`.
- **Co robi**: proxy/router do **Ollamy na SOLARIA** (`http://solaria:11434/api/generate`).
Dwa endpointy: `POST /api/chat` → model `deepcoder:14b`; `POST /api/code` → model
`deepseek-coder:latest` (z twardym promptem "return only code/command" + heurystyka
`looks_like_shell_command`). `GET /` = healthcheck (`{"status": "gateway ok"}`).
- **Kto go wola dzis**: zaden kontener agent-system-\* nie ma env wskazujacego na
llm-gateway (telegram-bot ma `CONTROL_PLANE_URL=http://webui:8080` — to WEWNETRZNY
webui w sieci compose, nie llm-gateway; jego `ENABLE_LLM_FALLBACK=false` uzywa
`OPENCLAW_BASE_URL`, nie gatewaya). Jedyny ruch: Prometheus (blednie, patrz nizej).
To infrastruktura "na zawolanie" dla agentow, nie martwy kod.
- **Gdzie zrodlo**: `/opt/llm-gateway` NIE jest repo git. Przeszukano PIHA
(`/opt`, `/home/pi`, `/home/oskar`, maxdepth) — **jedyna kopia `main.py` to
`/opt/llm-gateway/app/main.py`**. W repo homelab-codex brak zrodla (tylko wzmianki
w docs; `ollama_client.py` w korzeniu repo gada z Ollama bezposrednio, nie przez
gateway). **Status: kod tylko na dysku PIHA — DO ZARCHIWIZOWANIA** (backlog).
- Znany bug konfiguracyjny monitoringu: Prometheus na PIHA ma target nazwany
`watchtower` celujacy w :8080 i odpytujacy `/v1/metrics` → wieczne 404 w logach
gatewaya (backlog).
### Korekta 2: immich ZOSTAJE NA PIHA NA STALE
Rekomendacja "przenies na SOLARIA" wykreslona: immich musi byc dostepny **24/7**
(vhosty immich.okit.pl / foty.kapala.org), a SOLARIA jest wlaczana **sesyjnie**
nie nadaje sie na hosting always-on. Wiersze immich_\* w tabeli glownej czytac jako
**ZOSTAW** (kategoria PRZENIES niewazna).
### Korekta 3: reszta kandydatow "DECYZJA OSKARA" — ZOSTAJE
forgejo_dind, code-server, portainer, mqtt-exporter (kontener) — wszystkie zostaja
bez zmian. Duplikat mqtt-exporter i limit 2000 metryk pozostaja w backlogu jako
osobny temat.
### Egzekucja: elasticsearch + diskover UBITE (jedyne dwa)
Wykonane 2026-07-02 ~16:28 CEST na PIHA, w kolejnosci z audytu (najpierw diskover):
1. Oba kontenery = jeden compose project `diskover` (`/home/pi/diskover/docker-compose.yml`),
restart `unless-stopped`; brak jednostek systemd i wpisow cron — jedyny mechanizm
autostartu to same kontenery.
2. `docker stop diskover``docker stop elasticsearch` — czysto (Exited 0 / 143).
3. Obserwacja ~2 min: zero restart-loopow, logi wikijs ciche, nic nie krzyczy.
4. `docker compose -p diskover down` — kontenery usuniete, siec `diskover_default`
usunieta. Po reboocie nic ich nie wskrzesi (kontenery nie istnieja).
5. **Dane ES NIE skasowane**: bind mount `/home/pi/diskover/esdata` (indeks
`diskover-pimedia`, ~22MB) zostal na dysku nietkniety — `compose down` nie rusza
bind mountow. Obrazy tez zostawione (ewentualne `docker image prune` = osobna decyzja).
### Zysk faktyczny
| Metryka | Przed (16:27) | Po (16:31) | Delta |
|---|---|---|---|
| RAM available | 2.8Gi | **3.8Gi** | **+1.0Gi** |
| RAM used | 5.1Gi | 4.1Gi | 1.0Gi |
| Swap used | 2.0Gi | 1.9Gi | 0.1Gi (spadek presji; pelny efekt po czasie) |
| Kontenery Up | 41 | 39 | 2 (elasticsearch, diskover) |
Kryterium modulu 0 (**>= 1.5Gi available stabilnie**) — **SPELNIONE** z zapasem
(3.8Gi), bez ruszania immich i llm-gateway. Zysk zgodny z prognoza audytu
(~902Mi rezydentne + strony ES wyswapowane).