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>
32 KiB
| okf | type | visibility | status | updated | as_of | links |
|---|---|---|---|---|---|---|
| 0.1 | audit | private | active | 2026-07-14 | 2026-07-14 |
Monitoring coverage — co biega vs co jest monitorowane (recon 2026-07-14)
Pytanie: czy wszystkie serwisy floty są monitorowane? Odpowiedź krótka: NIE. Biega 76 kontenerów na 5 osiągalnych węzłach, alertowanych jest 15 (~20%). 61 kontenerów działa bez alertowania — w tym krytyczne: vaultwarden (hasła), forgejo (git = źródło prawdy GitOps), immich (zdjęcia), homeassistant5 (dom), obie instancje NPM (ingress), agent-system-telegram-bot (sam kanał alertów).
Metadane zbierania danych
| Data zebrania | 2026-07-14, 17:16–17:17 UTC |
| Metoda | docker ps --format '{{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}' |
| PIHA | ssh piha (100.108.208.3, user oskar) — 17:16:37Z |
| VPS | ssh vps (100.95.58.48, user oskar) — 17:16:39Z |
| SOLARIA | lokalnie (sesja biegła na solarii) — 17:16:41Z |
| LUSTRO | ssh pi@100.99.85.73 (uwaga: user pi, nie oskar) — 17:17:11Z |
| SATURN | ssh oskar@100.121.168.72 — 17:17:21Z |
| CHELSTY-INFRA / CHELSTY-HA | OFFLINE — tailscale status: last seen 42 dni temu. Do weryfikacji po powrocie online. |
| Kod | branch task/monitoring-coverage-recon @ parent d5139c9 (master) |
Sekcje A–C to STAN NA DZIEŃ ZBIERANIA (zmienny — przy odświeżaniu przewalidować w całości). Sekcja E (klasyfikacja) i F (plan) to DECYZJE (trwałe — przy odświeżaniu tylko dopisać nowe kontenery).
Jak działa monitoring w tym systemie (zweryfikowane w kodzie, stan na d5139c9)
Warstwy, od detekcji do alertu:
- node-agent (
services/node-agent/src/node_agent.py,check_containers()~linia 305): czyta docker socket i emituje eventy dla WSZYSTKICH kontenerów z restart policy (unless-stopped/always/on-failure) — NIE filtruje po services.yaml. Emituje:containers_not_running(exited/dead),healthcheck_failed(running+unhealthy),service_healthy(running). Kontenery w staniecreatedpomija. Uwaga (gap): kontener w stanierestarting(crash-loop) nie pasuje ani doexited/deadani dorunning— crash-loop nie generuje żadnego eventu (zaobserwowane na lustro/watchtower, patrz niżej). Nazwa kanoniczna = labelcom.docker.compose.service(fallback: nazwa kontenera). Zdeployowany na: piha, vps, solaria, lustro (na saturnie NIE). - stability-agent (
services/stability-agent/src/stability_agent.py): również raportuje wszystkie kontenery (bez filtra) — eventycontainers_not_running,mqtt_unreachable,disk_usage_high+ publikacja do Redis. Biega na piha, vps, solaria (poza services.yaml!). - Observer (
scripts/observer/observer.py, uruchamiany w control-plane@VPS): syntetyzuje eventy do/opt/homelab/world/{services,nodes,incidents}.json. Rejestruje wszystko (na dziś 116 wpisów w services.json, w tym wszystkie shadow kontenery). Widoczność ≠ alert. - Supervisor (
services/control-plane/src/supervisor.py,reconcile()linia 288): generuje akcje (redeploy/container_restart→ pending → Telegram → operator) WYŁĄCZNIE dla serwisów zadeklarowanych whosts/<node>/services.yaml(_load_desired_state(), linie 161–195). Flagamonitor: false(linie 182–186) wyklucza serwis z desired-state — serwis jest udokumentowany, ale supervisor go pomija. To jest jedyny filtr: detekcja jest flotowa, alertowanie tylko dla zadeklarowanych. Dodatkowo supervisor routuje niezależnie od desired-state: eventyha_*(z ha-diag-agent),node_offline/stale/online(liveness węzłów z heartbeatów node-agenta) idisk_pressure. - fleet-prometheus (
services/fleet-prometheus/, VPS): scrape node_exporterów = liveness HOSTA, nie serwisów. Scrape'uje: vps, piha, solaria, lustro. Świadomie NIE: saturn (workstation, często off), chelsty (LTE, exporter DOWN — do zbadania osobno). AlertNodeDown(rules/liveness.yml) tylko dlavps|piha(solaria/lustro bywają planowo wyłączane). Bez Alertmanagera — alerty odbiera brain-watchdog. - brain-watchdog (
services/brain-watchdog/, PIHA): pilnuje świeżości control-plane (/summary) + pollujePROMETHEUS_URL/api/v1/alertsi forwarduje do Telegrama. - ha-diag-agent (piha → HA "ken" localhost:8123; chelsty-infra → chelsty-ha): diagnostyka
HA (websocket, integracje, encje) → supervisor routuje na alert/restart niezależnie od
services.yaml (dziś wisi
container-restart-piha-homeassistantmimo braku wpisu HA w hosts/piha/services.yaml).
Definicja "monitorowany" w tym raporcie = supervisor wygeneruje akcję/alert gdy serwis
padnie = wpis w hosts/<node>/services.yaml bez monitor: false, z nazwą zgodną z nazwą
compose-service kontenera.
A. Stan faktyczny — pełne listy kontenerów (STAN NA 2026-07-14)
PIHA — 42 kontenery
| Kontener | Obraz | Status | Porty |
|---|---|---|---|
| node-agent | node-agent-node-agent | Up 22h (healthy) | — |
| paperless | ghcr.io/paperless-ngx/paperless-ngx:2.14 | Up 47h (healthy) | 192.168.31.5:8210→8000 |
| vikunja | vikunja/vikunja:latest | Up 4d | 0.0.0.0:3456→3456 |
| vikunja-db | postgres:16-alpine | Up 4d (healthy) | 5432 (internal) |
| brain-watchdog | brain-watchdog-brain-watchdog | Up 4d (healthy) | — |
| paperless-db | postgres:16-alpine | Up 4d (healthy) | 192.168.31.5:5434→5432 |
| paperless-broker | redis:7-alpine | Up 4d (healthy) | 192.168.31.5:6380→6379 |
| llm-gateway | llm-gateway-llm-gateway | Up 11d (healthy) | 100.108.208.3:8080→8080 |
| kb-postgres | pgvector/pgvector:pg16 | Up 2w (healthy) | 0.0.0.0:5433→5432 |
| agent-system-webui | agent-system-webui | Up 2w | 0.0.0.0:18180→8080 |
| agent-system-runtime-materializer | agent-system-runtime-materializer | Up 2w | — |
| agent-system-telegram-bot | agent-system-telegram-bot | Up 2w | — |
| ha-diag-agent | ha-diag-agent-ha-diag-agent | Up 2w (healthy) | — |
| stability-agent | stability-agent-stability-agent | Up 2w (healthy) | — |
| agent-system-redis | redis:7 | Up 2w | 0.0.0.0:6379→6379 |
| nginxproxymanager-app-1 | jc21/nginx-proxy-manager:latest | Up 2w | 0.0.0.0:80-81→80-81, 443→443 |
| homeassistant5 | ghcr.io/home-assistant/home-assistant:stable | Up 2w | (host network, :8123) |
| immich_server | ghcr.io/immich-app/immich-server:release | Up 2w (healthy) | 0.0.0.0:2283→2283, 8081-8082 |
| immich_postgres | tensorchord/pgvecto-rs:pg14-v0.2.0 | Up 2w (healthy) | 5432 (internal) |
| immich_machine_learning | ghcr.io/immich-app/immich-machine-learning:release | Up 2w (healthy) | — |
| immich_redis | redis:6.2-alpine | Up 2w (healthy) | 6379 (internal) |
| forgejo_dind | docker:dind | Up 2w | 2375-2376 (internal) |
| forgejo | codeberg.org/forgejo/forgejo:7 | Up 12d | 0.0.0.0:3000→3000, 222→22 |
| forgejo-db-1 | postgres:14 | Up 2w | 5432 (internal) |
| zigbee2mqtt | koenkk/zigbee2mqtt | Up 3d | 0.0.0.0:8087→8080 |
| audiobookshelf | ghcr.io/advplyr/audiobookshelf:latest | Up 2w | 0.0.0.0:13378→80 |
| grafana | grafana/grafana-enterprise:latest | Up 2w | 0.0.0.0:9003→3000 |
| wikijs-db-1 | postgres:15-alpine | Up 2w | 5432 (internal) |
| code-server | lscr.io/linuxserver/code-server:latest | Up 2w | 0.0.0.0:8443→8443 |
| portainer | portainer/portainer-ce:latest | Up 2w | 0.0.0.0:8008→8000, 9009→9000 |
| prom | prom/prometheus:latest | Up 2w | 0.0.0.0:9090→9090 |
| homepage | ghcr.io/gethomepage/homepage:latest | Up 2w (healthy) | 0.0.0.0:3033→3000 |
| actual-server | actualbudget/actual-server:latest-alpine | Up 2w | 0.0.0.0:5006→5006 |
| mqtt-exporter-mqtt-exporter-1 | kpetrem/mqtt-exporter:latest | Up 2w | 0.0.0.0:9000→9000 |
| node-exporter | quay.io/prometheus/node-exporter:latest | Up 2w | — |
| wikijs-wiki-1 | ghcr.io/requarks/wiki:2 | Up 2w | 0.0.0.0:3300→3000 |
| owntracks-recorder | owntracks/recorder:latest | Up 2w | 0.0.0.0:8083→8083 |
| vaultwarden | vaultwarden/server:latest | Up 2w (healthy) | 0.0.0.0:3012→80 |
| pihole-exporter | ekofr/pihole-exporter:latest | Up 2w | 0.0.0.0:9617→9617 |
| fail2ban-prometheus-exporter-exporter-1 | registry.gitlab.com/hctrdev/fail2ban-prometheus-exporter:latest | Up 2w (unhealthy) | 0.0.0.0:9191→9191 |
| owntracks-prometheus-exporter-prometheus-owntracks-exporter-1 | linusgroh/prometheus-owntracks-exporter | Up 2w | 0.0.0.0:8780→80 |
| own-tracks-frontend-owntracks-frontend-1 | owntracks/frontend | Up 2w | 0.0.0.0:8084→80 |
Zmiany vs audyt 2026-06-30 (kb/subsystems/fleet-inventory.md): przybyły paperless,
paperless-db, paperless-broker (Deploy 1, 2026-07-10); zniknęły diskover i elasticsearch
(w audycie 06-30 były w 33 shadow; dziś nie biegają). 06-30: 40 kontenerów → dziś: 42.
VPS — 24 kontenery
| Kontener | Obraz | Status | Porty |
|---|---|---|---|
| control-plane-executor | control-plane-executor | Up 46m (healthy) | — |
| control-plane-observer | control-plane-observer | Up 46m (healthy) | — |
| control-plane-supervisor | control-plane-supervisor | Up 46m (healthy) | — |
| control-plane-ui | control-plane-operator-ui | Up 46m (healthy) | 0.0.0.0:18180→8080 |
| fleet-prometheus | prom/prometheus:v3.5.0 | Up 2w (healthy) | 100.95.58.48:9090→9090 |
| node-agent | node-agent-node-agent | Up 2w (healthy) | — |
| humanai-mailer | humanai-mailer | Up 2w | — |
| humanai-landing | humanai-landing | Up 2w | 80 (internal) |
| umami | ghcr.io/umami-software/umami:postgresql-latest | Up 2w (healthy) | 3000 (internal) |
| umami-db | postgres:16-alpine | Up 2w (healthy) | 5432 (internal) |
| node_exporter | quay.io/prometheus/node-exporter:latest | Up 5w | (host network :9100) |
| stability-agent | stability-agent-stability-agent | Up 5w (healthy) | — |
| outline-outline-1 | outlinewiki/outline:1.6.1 | Up 5w (healthy) | 0.0.0.0:3000→3000 |
| outline-postgres-1 | 4e6e670bb069 (anonimowy image ID!) | Up 5w (healthy) | 5432 (internal) |
| outline-redis-1 | redis:7-alpine | Up 5w (healthy) | 6379 (internal) |
| ai-cluster-service-ops-worker-1 | ai-cluster-service-ops-worker | Up 5w | — |
| ai-cluster-codex-worker-1 | ai-cluster-codex-worker | Up 5w | — |
| ai-cluster-openclaw-1 | ai-cluster-openclaw | Up 5w (healthy) | 0.0.0.0:8000→8000 |
| ai-cluster-planner-worker-1 | ai-cluster-planner-worker | Up 5w | — |
| ai-cluster-redis-1 | redis:7-alpine | Up 5w | 6379 (internal) |
| mosquitto | eclipse-mosquitto:2 | Up 5w | 100.95.58.48:1883→1883 |
| joplin-server | joplin/server:latest | Up 5w | 127.0.0.1:22300→22300 |
| npm | jc21/nginx-proxy-manager:latest | Up 5w | 0.0.0.0:80-81→80-81, 443→443 |
| joplin-db | postgres:18 (pre-release tag!) | Up 5w (healthy) | 5432 (internal) |
gokapi NIE biega mimo deklaracji w hosts/vps/services.yaml — supervisor poprawnie to wykrył:
w /opt/homelab/actions/pending/ wisi redeploy-vps-gokapi.json. To dowód, że monitoring
desired-state DZIAŁA dla zadeklarowanych serwisów.
SOLARIA — 5 kontenerów
| Kontener | Obraz | Status | Porty |
|---|---|---|---|
| paperless-worker | ghcr.io/paperless-ngx/paperless-ngx:2.14 | Up 5h (healthy) | 8000 (internal) |
| planner-agent | planner-agent-planner-agent | Up 5h (healthy) | — |
| node-agent | node-agent-node-agent | Up 5h (healthy) | — |
| stability-agent | stability-agent-stability-agent | Up 5h (healthy) | — |
| node_exporter | quay.io/prometheus/node-exporter:latest | Up 5h | (host network :9100) |
LUSTRO — 4 kontenery
| Kontener | Obraz | Status | Porty |
|---|---|---|---|
| node-agent | node-agent-node-agent | Up 20h (healthy) | — |
| node-exporter | quay.io/prometheus/node-exporter:latest | Up 20h | (host network :9100) |
| piper-tts | piper-tts-rpi5 | Up 20h | 0.0.0.0:5000→5000, 10200→10200 |
| pi-watchtower-1 | containrrr/watchtower | Restarting (1) — crash-loop! | — |
pi-watchtower-1 jest w crash-loopie i przez lukę w node-agencie (stan restarting nie
generuje eventu, patrz sekcja o mechanizmie) — nikt tego nie widzi; world-state pokazuje
lustro/watchtower healthy (stary event service_healthy).
SATURN — 1 kontener
| Kontener | Obraz | Status | Porty |
|---|---|---|---|
| agent-system-webui | agent-system-webui | Up 9h | 0.0.0.0:8080→8080 |
Stack control-plane z audytu 06-30 (executor/observer/supervisor/ui) już NIE biega na saturnie — posprzątane. Saturn nie ma node-agenta, nie ma services.yaml, nie jest scrape'owany przez fleet-prometheus → węzeł całkowicie poza monitoringiem (świadomie: workstation, często off).
CHELSTY-INFRA / CHELSTY-HA — OFFLINE (42 dni)
Niedostępne przez Tailscale (last seen ~2026-06-02). Deklaracje: chelsty-infra = ha-diag-agent,
node-agent, mosquitto, zigbee2mqtt, frigate; chelsty-ha = homeassistant (monitor: false).
world/services.json nadal pokazuje serwisy chelsty-infra jako "healthy" — to STĘCHŁY stan
(status serwisów nie wygasa; liveness wygasa tylko na poziomie węzła). Do weryfikacji po
powrocie online, w tym: czy alerty node_offline dla chelsty odpaliły 42 dni temu.
B. Stan deklarowany — hosts//services.yaml (STAN NA 2026-07-14)
| Węzeł | Zadeklarowane serwisy | monitor: false? |
|---|---|---|
| piha | ha-diag-agent, node-agent, brain-watchdog, vikunja, llm-gateway, kb-postgres | — |
| vps | node-agent, control-plane, node_exporter, fleet-prometheus, gokapi | — |
| solaria | node-agent | — |
| lustro | node-agent | — |
| saturn | BRAK PLIKU services.yaml | — |
| chelsty-infra | ha-diag-agent, node-agent, mosquitto, zigbee2mqtt, frigate | — |
| chelsty-ha | homeassistant | TAK (node-agent tam nie zdeployowany; HA kryty pośrednio przez MQTT) |
Razem: 18 deklaracji alertowalnych (w tym 5 na offline'owym chelsty-infra) + 1 z monitor:false.
Uwaga: stability-agent ma katalogi w hosts/{piha,solaria,vps}/runtime/, ale NIE ma wpisów
w żadnym services.yaml — sam strażnik nie jest pilnowany.
C. Luka — biega, ale poza alertowaniem (STAN NA 2026-07-14)
Pokrycie per węzeł (kontenery alertowane / biegające):
| Węzeł | Biega | Alertowane | Luka |
|---|---|---|---|
| PIHA | 42 | 6 (node-agent, ha-diag-agent, brain-watchdog, vikunja, llm-gateway, kb-postgres) | 36 |
| VPS | 24 | 7 (node-agent, control-plane ×4¹, node_exporter, fleet-prometheus) | 17 |
| SOLARIA | 5 | 1 (node-agent) | 4 |
| LUSTRO | 4 | 1 (node-agent) | 3 |
| SATURN | 1 | 0 | 1 |
| RAZEM | 76 | 15 | 61 (~80%) |
¹ control-plane to 1 deklaracja pokrywająca 4 kontenery — node-agent na VPS probe'uje endpoint
HTTP :18180/summary i emituje service_healthy/service_unhealthy dla logicznego serwisu
"control-plane" (_check_control_plane_health()).
Częściowe pokrycie (nie liczone jako "alertowane" powyżej):
- homeassistant5@piha — ha-diag-agent pilnuje websocketu HA i supervisor generuje
container_restart/alert_onlyniezależnie od services.yaml. Padnięcie HA zostanie zauważone. Brak jednak wpisu desired-state (drift "kontener zniknął" nie będzie wykryty). - node-exporter@piha — jego padnięcie =
up==0w fleet-prometheus = alert NodeDown (piha) przez brain-watchdog → Telegram. Pośrednio alertowany. - node_exporter@solaria, node-exporter@lustro — scrape'owane, ale świadomie wyłączone z reguły NodeDown (węzły planowo wyłączane) → brak alertu.
- gokapi@vps — zadeklarowany, NIE biega; drift poprawnie wykryty (pending
redeploy-vps-gokapi.json). Luka deploymentu, nie monitoringu.
D. Nowe serwisy KB — weryfikacja wpisu z backlogu (f135365)
Backlog ("Nowe serwisy KB nie sa w monitoringu", 2026-07-12) potwierdzony w połowie — paperless i paperless-worker faktycznie poza monitoringiem; gokapi/llm-gateway/kb-postgres są OK:
| Serwis | services// w repo? | hosts/*/services.yaml? | Biega? | Alertowany? |
|---|---|---|---|---|
| paperless (+db, +broker) | ✓ (+ hosts/piha/runtime/paperless) | ✗ | ✓ piha (healthy) | ✗ LUKA |
| paperless-worker | ✓ (owner_node: solaria) | ✗ | ✓ solaria (healthy) | ✗ LUKA |
| nextcloud | ✓ (owner_node: piha, commit 7e5577c) |
✗ | ✗ nigdzie (nie zdeployowany) | ✗ (nie dotyczy — dodać wpis RAZEM z deployem) |
| gokapi | ✓ (owner_node: vps) | ✓ hosts/vps | ✗ nie biega | ✓ — drift wykryty, wisi redeploy-vps-gokapi |
| llm-gateway | ✓ (owner_node: piha) | ✓ hosts/piha | ✓ piha (healthy) | ✓ |
| kb-postgres | ✓ (owner_node: piha) | ✓ hosts/piha | ✓ piha (healthy) | ✓ |
E. Klasyfikacja niemonitorowanych kontenerów (DECYZJA — trwała)
Kategorie:
- A (pełny GitOps): krytyczny — docelowo compose w
services/, service.yaml, deploy przez deploy.sh. Każde A dostaje NAJPIERW wpis monitoringowy (krok B) — tanio, od razu. - B (tylko monitoring): deployment zostaje jak jest; dodać do
hosts/<node>/services.yaml→ supervisor alarmuje gdy padnie. - C (świadomie poza): padnięcie nie boli / narzędzie jednorazowe. Uzasadnienie obowiązkowe.
Kontenery pomocnicze stacka (db/redis/broker) dziedziczą kategorię stacka — w services.yaml deklaruje się serwis główny (padnięcie db zwykle wywala healthcheck głównego kontenera).
PIHA (36 luk)
| Kontener | Co robi | Kategoria | Uzasadnienie |
|---|---|---|---|
| vaultwarden | menedżer haseł | A (najpierw B) | Hasła całej rodziny — padnięcie/utrata danych boli maksymalnie; musi być w GitOps z backupem i alertem |
| forgejo, forgejo-db-1, forgejo_dind | git hosting + CI | A (najpierw B) | Źródło prawdy GitOps + OIDC dla vikunji; bez forgejo nie ma deployów; już zidentyfikowane w audycie 06-30 (owner_node błędnie=saturn) |
| homeassistant5 | Home Assistant "ken" (dom) | A (najpierw B) | Automatyka domu; częściowo kryty przez ha-diag-agent (websocket), ale bez wpisu desired-state; wpis homeassistant w services.yaml domknie lukę |
| immich_server, immich_postgres, immich_machine_learning, immich_redis | zdjęcia rodzinne | A (najpierw B) | Dane niereprodukowalne (zdjęcia); padnięcie = brak backupu telefonów w tle, zauważalne późno |
| nginxproxymanager-app-1 | ingress LAN (*.kapala.org: HA, immich, paperless, cloud…) | A (najpierw B) | Pojedynczy punkt wejścia do wszystkich usług domowych; padnięcie = "wszystko nie działa" |
| paperless, paperless-db, paperless-broker | KB: dokumenty (OCR pipeline) | B | Już w GitOps (services/paperless + runtime override) — brakuje TYLKO wpisu w services.yaml; przypadek z backlogu f135365 |
| stability-agent | watchdog węzła | B | Repo-managed (runtime override jest); strażnik musi być pilnowany; dotyczy też vps i solarii |
| zigbee2mqtt | bridge Zigbee→MQTT (ken) | B | services/zigbee2mqtt istnieje (owner=piha); sensory domowe przestają raportować gdy padnie |
| agent-system-telegram-bot | kanał alertów Telegram | B | Jak padnie, ŻADEN alert nie dojdzie — a nikt się nie dowie; pilnować w pierwszej kolejności |
| agent-system-webui | operator UI (approve akcji) | B | Bez niego nie da się zatwierdzać akcji z przeglądarki; część pętli human-in-the-loop |
| agent-system-redis | redis dla agent-system | B | Zależność telegram-bota i webui; tani wpis |
| agent-system-runtime-materializer | materializacja runtime agentów | B | Część stacka agent-system; padnięcie cichaczem psuje odświeżanie stanu |
| wikijs-wiki-1, wikijs-db-1 | wiki | B | Notatki/dokumentacja domowa — padnięcie boli umiarkowanie, wpis jest tani |
| actual-server | budżet domowy | B | Dane finansowe; używany regularnie, padnięcie zauważalne przy wpisywaniu wydatków |
| prom | domowy Prometheus (LAN) | B | Źródło metryk domowych (HA, piha OS); padnięcie = dziura w historii; UWAGA: ma plaintext token HAOS (anti-pattern, patrz services/fleet-prometheus/prometheus.yml komentarz) |
| owntracks-recorder | lokalizacja rodziny (backend) | C | Hobby/eksperyment; padnięcie = luka w śladzie lokalizacji, nie boli operacyjnie |
| own-tracks-frontend-… | frontend owntracks | C | Czysta wizualizacja |
| owntracks-prometheus-exporter-… | exporter owntracks | C | Pomocniczy; objaw padnięcia = brak metryk, widoczny w grafanie |
| mqtt-exporter-mqtt-exporter-1 | exporter MQTT→prom | C | Jak wyżej |
| pihole-exporter | exporter pihole | C | Jak wyżej |
| fail2ban-prometheus-exporter-… | exporter fail2ban | C | Jak wyżej; DZIŚ unhealthy — naprawić lub usunąć (follow-up) |
| node-exporter | metryki hosta dla fleet-prometheus | C | Pośrednio alertowany: padnięcie = up==0 = NodeDown(piha) przez brain-watchdog |
| grafana | dashboardy | C | Wizualizacja; padnięcie zauważalne przy wejściu, zero utraty danych (provisioning/db na dysku) |
| homepage | strona startowa | C | Kosmetyka |
| audiobookshelf | audiobooki | C | Media; restart ręczny wystarczy |
| code-server | IDE w przeglądarce | C | Narzędzie dev, używane ad-hoc |
| portainer | GUI dockera | C | Narzędzie administracyjne ad-hoc; wręcz kandydat do usunięcia (GitOps ma być źródłem prawdy) |
VPS (17 luk)
| Kontener | Co robi | Kategoria | Uzasadnienie |
|---|---|---|---|
| npm | publiczny ingress okit.pl | A (najpierw B) | Cała publiczna powierzchnia (share.okit.pl, vikunja.okit.pl…); manifesty A już istnieją na NIEZMERGOWANEJ gałęzi feat/vps-service-migration (commit 862c04a, cutover niewykonany) |
| mosquitto | broker MQTT ai-cluster | B | services/mosquitto istnieje ale owner_node=piha (błąd — biega na VPS od tygodni, audyt 06-30 poz. 3); szyna komunikacji ai-cluster |
| stability-agent | watchdog węzła | B | Jak na piha |
| outline-outline-1, outline-postgres-1, outline-redis-1 | wiki zespołowa | B | Notatki; manifesty na gałęzi feat/vps-service-migration; przy okazji naprawić anonimowy image ID postgresa (audyt 06-30 poz. 19) |
| joplin-server, joplin-db | sync notatek | B | Notatki osobiste; przy okazji zejść z postgres:18 pre-release (audyt 06-30 poz. 20) |
| ai-cluster-codex-worker-1, ai-cluster-planner-worker-1, ai-cluster-service-ops-worker-1, ai-cluster-openclaw-1, ai-cluster-redis-1 | workery agentowe | B | Padnięcie = agenci przestają mielić kolejki (objawia się późno); docelowo migracja compute na SOLARIA (CLAUDE.md), monitoring dodać już teraz |
| humanai-landing, humanai-mailer | strona publiczna + mailer | B | Publiczna wizytówka — padnięcie boli reputacyjnie i cicho (nikt nie patrzy); brak w repo (audyt 06-30 poz. 21) |
| umami, umami-db | analityka www | C | Statystyki odwiedzin; padnięcie = luka w danych analitycznych, nie boli operacyjnie |
SOLARIA (4 luki)
| Kontener | Co robi | Kategoria | Uzasadnienie |
|---|---|---|---|
| paperless-worker | OCR/konsument kolejki KB | B | Przypadek wprost z backlogu f135365: "jesli worker padnie (…) dowiesz sie po tym, ze kolejka nie jest przetwarzana"; repo+runtime są, brakuje wpisu |
| planner-agent | agent planowania | B | services/planner-agent istnieje (owner=solaria ✓); audyt 06-30 poz. 14 |
| stability-agent | watchdog węzła | B | Jak na piha/vps |
| node_exporter | metryki hosta | C | Scrape'owany, ale solaria świadomie poza NodeDown (planowe wyłączenia); alerting wróci z anomaly-detection (backlog) |
LUSTRO (3 luki)
| Kontener | Co robi | Kategoria | Uzasadnienie |
|---|---|---|---|
| piper-tts | TTS dla magic mirror | C | Padnięcie = lustro nie mówi; kosmetyka. Jeśli tani wpis — można podnieść do B przy okazji |
| node-exporter | metryki hosta | C | Jak solaria — świadomie poza NodeDown |
| pi-watchtower-1 | auto-update obrazów | C + follow-up PILNY | DZIŚ w crash-loopie, niewykrywalnym przez node-agent (luka na stan restarting). Decyzja operatora: naprawić albo USUNĄĆ (watchtower na edge = niekontrolowane pulle, sprzeczne z GitOps) |
SATURN (1 luka)
| Kontener | Co robi | Kategoria | Uzasadnienie |
|---|---|---|---|
| agent-system-webui | operator UI (kopia dev?) | C | Saturn = workstation, często wyłączony; świadomie poza monitoringiem (jak w fleet-prometheus). Wyjaśnić czemu biega duplikat UI z pihy (follow-up) |
F. Plan domknięcia — paczki na jedną sesję każda (DECYZJA — trwała)
Zasada procesowa (z backlogu, do utrwalenia): wpis w hosts/<node>/services.yaml +
inventory/topology.yaml to CZĘŚĆ deployu każdego nowego serwisu, nie osobny krok "kiedyś".
⚠ Gotcha techniczna dla WSZYSTKICH paczek (sprawdzić przed każdym wpisem): supervisor
matchuje klucz node/nazwa-serwisu z nazwą kanoniczną kontenera = label
com.docker.compose.service (node_agent.py _canonical_container_name()). Dla stacków
compose'owych to NIE jest nazwa kontenera: np. nginxproxymanager-app-1 ma compose-service
"app", wikijs-wiki-1 → "wiki", stąd w world/services.json wiszą kolizyjne klucze typu
piha/app, piha/db, piha/redis, piha/database. Przed dodaniem wpisu sprawdzić na hoście:
docker inspect <kontener> --format '{{ index .Config.Labels "com.docker.compose.service" }}'
— i jeśli label koliduje/jest ogólnikowy, najpierw nadać container_name + porządny compose
project name albo poprawić observer (patrz follow-upy). Bez tego wpis będzie wiecznym
missing_service i zaspamuje kolejkę akcji.
Paczka 1 — KB + już-zGitOps'owane serwisy (najtańsza-najważniejsza; czysta kategoria B)
Serwisy, które JUŻ są w repo (services/ + runtime overrides) — brakuje tylko rejestracji:
hosts/piha/services.yaml: + paperless, + stability-agent, + zigbee2mqtthosts/solaria/services.yaml: + paperless-worker, + planner-agent, + stability-agenthosts/vps/services.yaml: + stability-agent, + npm, + mosquitto (i naprawićservices/mosquitto/service.yamlowner_node: piha→vps orazservices/npm— potwierdzić że nazwa compose-service = "npm")inventory/topology.yaml: dopisać ww. do sekcji węzłów- Weryfikacja: po 1–2 cyklach supervisora
world/services.jsonma klucze o zgodnych nazwach, kolejka pending NIE zawiera fałszywychmissing_service; test driftu:docker stop paperless-workerna chwilę → pojawia się akcja →docker start→ akcja auto-cancelled (test wymaga zgody operatora; alternatywnie tylko obserwacja biernie) - Domknięcie wiszącego driftu: zdeployować gokapi na VPS (akcja
redeploy-vps-gokapijuż czeka na approve) — UWAGA: brakhosts/vps/runtime/gokapi/docker-compose.override.ymlz mem_limit (reguła VPS 4GB) — dodać przed deployem.
Paczka 2 — krytyczne shadow na PIHA (kategoria B dla przyszłych A)
Wpisy monitoringowe (bez ruszania deploymentu!) dla: vaultwarden, forgejo, homeassistant (kontener homeassistant5), immich, nginxproxymanager (compose-service prawdopodobnie "app" — patrz gotcha!), agent-system (telegram-bot, webui, redis, runtime-materializer), wikijs, actual-server, prom. Każdy wpis poprzedzony sprawdzeniem compose-label na hoście. Jeśli labels kolidują (db/app/redis) — najpierw follow-up "canonical naming" (niżej) albo wpis odroczony z adnotacją.
Paczka 3 — VPS shadow (kategoria B + przygotowanie cutover)
- Wpisy: outline, joplin, ai-cluster, humanai-landing, humanai-mailer (+ umami jeśli tanio)
- Przejrzeć gałąź
feat/vps-service-migration(commit862c04a: manifesty npm/outline/joplin/ ai-cluster; cutover NIE wykonany) — zdecydować: merge + cutover per checklista z CLAUDE.md, czy przepisać od nowa. UWAGA: CLAUDE.md już dziś twierdzi "All VPS services are now GitOps-managed" — to NIEPRAWDA na masterze; poprawić doc albo zmergować gałąź.
Paczka 4 — pełny GitOps dla krytycznych (kategoria A; JEDEN serwis = JEDNA sesja)
Kolejność wg bólu: 1) vaultwarden, 2) forgejo, 3) npm@piha + npm@vps (cutover), 4) immich,
5) homeassistant5. Dla każdego: compose do services/<name>/, service.yaml, env.example,
healthcheck.sh, runtime override w hosts/piha/runtime/, deploy przez deploy.sh.
Reguła migracji danych: ścieżki danych zostają NA MIEJSCU (CLAUDE.md) — zero przenoszenia
wolumenów bez osobnego planu.
Paczka 5 — porządki i decyzje C (follow-upy)
- lustro/pi-watchtower-1: naprawić albo usunąć (crash-loop TERAZ; watchtower vs GitOps)
- piha/fail2ban-exporter: unhealthy od ≥2 tyg. — naprawić albo usunąć
- saturn/agent-system-webui: wyjaśnić czemu biega; usunąć jeśli pozostałość dev
- nextcloud: przy deployu (osobna sesja per plan KB) wpis do services.yaml OD RAZU
- chelsty: po powrocie online powtórzyć inwentaryzację (sekcja "Jak odświeżyć")
- saturn: decyzja czy dostaje node-agenta + services.yaml (dziś świadomie poza)
Follow-upy techniczne w kodzie monitoringu (poza zakresem tego reconu, do osobnych tasków)
- node-agent nie widzi stanu
restarting(crash-loop = cisza) — dodać gałąź dlastatus == "restarting"wcheck_containers()→ eventcontainers_not_runninglub nowy typcontainer_crash_loop. Dowód: lustro/pi-watchtower-1. - Kolizje nazw kanonicznych w observerze/node-agencie: label
com.docker.compose.servicebez project-name daje kluczepiha/db,piha/app,piha/redis(dziś w world/services.json są duplikaty typupiha/immich_serverIpiha/immich-server). Propozycja: klucz<project>_<service>albo preferować container_name gdy label jest ogólnikowy. - Stęchły world-state dla offline węzłów: serwisy chelsty-infra "healthy" 42 dni po zniknięciu węzła — status serwisu powinien degradować się razem z liveness węzła.
- Alerting solaria/lustro: świadomie wyłączone z NodeDown; docelowo anomaly detection (istniejący backlog "Plan: Monitoring floty — Prometheus jako źródło prawdy").
TL;DR
- Biega: 76 kontenerów (42 piha, 24 vps, 5 solaria, 4 lustro, 1 saturn); chelsty-infra/ha offline od ~42 dni — niezweryfikowane.
- Alertowane: 15 kontenerów przez 13 deklaracji desired-state (+ HA częściowo przez ha-diag-agent, + node-exporter@piha pośrednio przez NodeDown, + gokapi: zadeklarowany, niezdeployowany, drift POPRAWNIE wykryty i wisi w pending).
- Luka: 61 kontenerów (~80%) bez alertowania. Detekcja (node-agent/observer) widzi
wszystko; filtr jest w supervisorze — alertuje TYLKO to, co wpisane w
hosts/<node>/services.yaml(bezmonitor: false). - Najboleśniejsze luki: vaultwarden (hasła), forgejo (git), immich (zdjęcia), homeassistant5 (dom, częściowo kryty), npm ×2 (cały ingress), agent-system-telegram-bot (kanał alertów pilnujący wszystkiego innego, sam niepilnowany).
- Znaleziska przy okazji: lustro/watchtower w crash-loopie niewykrywalnym przez node-agent
(luka na stan
restarting); fail2ban-exporter@piha unhealthy; gokapi czeka na deploy; CLAUDE.md błędnie twierdzi że VPS jest w pełni GitOps (manifesty na niezmergowanej gałęzi). - Co najpierw: Paczka 1 (wpisy dla paperless, paperless-worker, stability-agent ×3, zigbee2mqtt, npm, mosquitto, planner-agent — wszystko już w repo, tylko rejestracja) → Paczka 2 (krytyczne shadow PIHA) → Paczka 3 (VPS) → Paczka 4 (pełny GitOps po kolei).
Jak odświeżyć ten dokument
-
Stan faktyczny (sekcja A) — jedna pętla (uwaga na userów ssh: lustro=pi, reszta=oskar; solaria/saturn wg tego skąd odpalasz):
for target in oskar@100.108.208.3 oskar@100.95.58.48 oskar@100.100.231.104 \ pi@100.99.85.73 oskar@100.121.168.72 oskar@100.98.91.98; do echo "===== $target =====" ssh -o ConnectTimeout=10 -o BatchMode=yes "$target" \ "date -u +%Y-%m-%dT%H:%M:%SZ; docker ps --format '{{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}'" done(kolejno: piha, vps, solaria, lustro, saturn, chelsty-infra; chelsty-infra pomiń jeśli offline)
-
Stan deklarowany (sekcja B):
grep -A2 "^services:" hosts/*/services.yaml+ ręcznie sprawdzić flagimonitor: false. -
Luka (sekcja C): porównać 1 z 2 per węzeł; pamiętać że 1 deklaracja może pokrywać stack wielokontenerowy (control-plane, vikunja) i że match idzie po labelu
com.docker.compose.service, nie po nazwie kontenera. -
Wiszące akcje/drifty:
ssh vps ls /opt/homelab/actions/pending/. -
Sekcje E–F: NIE odtwarzać — tylko dopisać nowe kontenery i odhaczyć wykonane paczki. Zmienić klasyfikację wolno tylko świadomą decyzją (to sekcje DECYZYJNE).