homelab-codex-ws/docs/infra/piha-slim-audit-2026-07-02.md
oskar 6b35afd2ea docs(infra): egzekucja odchudzania PIHA — ES+diskover ubite (+1.0Gi), llm-gateway/immich zostają
Faza 2 modułu 0 po review Oskara: elasticsearch+diskover usunięte (compose down,
dane esdata zostawione na dysku), available 2.8Gi -> 3.8Gi, kryterium >=1.5Gi
spełnione. llm-gateway udokumentowany (własny router LLM -> Ollama@SOLARIA,
źródło tylko w /opt/llm-gateway — archiwizacja w backlogu); immich zostaje na
PIHA na stałe (24/7, SOLARIA sesyjna).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 16:44:57 +02:00

17 KiB
Raw Blame History

Audyt odchudzania PIHA — 2026-07-02

Faza 1 (READ-ONLY) modulu 0 filaru dokumentow (docs/kb/modules/00-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 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 diskoverdocker 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).