host: piha services: ha-diag-agent: role: ha-diagnostic-agent deployment_model: docker-compose exposure: local-only offline_required: false depends_on: local: [] external: [homeassistant] config: target_url: http://localhost:8123 location_tag: "ken" events_dir: /opt/homelab/events/piha runtime: config_path: /opt/homelab/config/ha-diag-agent data_path: /var/lib/ha-diag-agent node-agent: role: node-stability-monitor deployment_model: docker-compose exposure: local-only offline_required: true depends_on: local: [] external: [] runtime: config_path: /opt/homelab/config/node-agent data_path: /opt/homelab/state logs_path: /opt/homelab/events brain-watchdog: role: control-plane-watchdog deployment_model: docker-compose exposure: private offline_required: false depends_on: local: [] external: [control-plane] runtime: config_path: /opt/homelab/config/brain-watchdog vikunja: role: task-management deployment_model: docker-compose exposure: private # public via npm reverse proxy at vikunja.okit.pl offline_required: false depends_on: local: [] external: [forgejo] # OIDC identity provider ports: - name: http container_port: 3456 protocol: tcp runtime: # secrets (.env) + OIDC config (config.yml) live alongside the compose file config_path: services/vikunja # data is in Docker named volumes: vikunja_vikunja_db, vikunja_vikunja_files llm-gateway: role: llm-router # FastAPI proxy -> Ollama @ SOLARIA :11434 deployment_model: docker-compose exposure: private # Tailscale-only bind (TAILSCALE_BIND_IP); no public ingress offline_required: false depends_on: local: [] external: [ollama] # SOLARIA may be powered down -> routes 502, health stays ok ports: - name: http container_port: 8080 protocol: tcp runtime: # .env (TAILSCALE_BIND_IP) lives alongside the compose file; stateless, no data path config_path: services/llm-gateway node_exporter: role: metrics-exporter deployment_model: docker-compose exposure: local-only offline_required: true depends_on: local: [] external: [] runtime: # textfile collector reads /opt/homelab/state/node-exporter (module 5 phase 3 step 5, # docs/kb/modules/05-faza3-plan.md §7.2 — kb-ingest.prom) via the existing /:/host:ro # mount, see hosts/piha/runtime/node_exporter/docker-compose.override.yml. data_path: /opt/homelab/state/node-exporter kb-postgres: role: kb-database # KB spine: Postgres 16 + pgvector (always-on) deployment_model: docker-compose exposure: local-only # Tailscale-accessible; no public ingress offline_required: false depends_on: local: [] external: [] ports: - name: postgres host_port: 5433 protocol: tcp runtime: config_path: /opt/homelab/config/kb-postgres # data is in Docker named volume kb_postgres_data — must land on the NVMe # (Docker data-root on /home); see hosts/piha/runtime/kb-postgres override. kb-query: role: kb-search-api # module 5 phase 4: FastAPI wrapper over kb_retrieval cascade/flat query deployment_model: docker-compose exposure: private # LAN bind (LAN_BIND_IP); npm@PIHA vhost + OIDC is a later step offline_required: false depends_on: local: [kb-postgres] external: [ollama] # SOLARIA may be offline -> /search 502/503, /healthz stays ok ports: - name: http container_port: 8080 host_port: 8230 protocol: tcp runtime: # .env (KB_DSN, LAN_BIND_IP) lives alongside the compose file; stateless, no data path config_path: services/kb-query