Files
homelab-monitor/CLAUDE.md
T
jhodgkin 9891751d37
CI / web (push) Successful in 17s
CI / api (push) Successful in 22s
docs: update CLAUDE.md for device discovery
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-12 20:50:50 -06:00

57 lines
4.0 KiB
Markdown

# Homelab Monitor — Project Memory
Unified health dashboard for the homelab (infra docs: `jhodgkin/homelab` repo, `docs/infrastructure.md`).
One login instead of logging into Proxmox, Zabbix, OMV, and every service separately.
## How to resume work in a new session
1. List open issues: `GET /api/v1/repos/jhodgkin/homelab-monitor/issues?state=open&limit=30` on
`git.jerodrigged.com` (same pattern as the main homelab backlog, see global `~/.claude/CLAUDE.md`).
Milestone `v1-dashboard` is the current focus; everything else is backlog.
2. Pick an issue, comment that you're starting it, do the work, comment what you did, close it.
3. Commit and push after every meaningful step — don't let work sit uncommitted.
## Architecture
- `apps/api` — Fastify + TypeScript. Polls **collectors** on an interval (`POLL_INTERVAL_SECONDS`,
default 30s), writes snapshots to SQLite (`apps/api/src/db`), serves `/api/*`.
- `apps/web` — React + Vite + TypeScript. Polls `/api/hosts` every 15s, renders host/container cards.
- `config/hosts.yaml` — declares *what* to monitor (no secrets, committed). Credentials live in `.env`
(gitignored) — see `.env.example` for the full list.
- Collectors implement the `Collector` interface (`apps/api/src/collectors/types.ts`) and are registered
in `apps/api/src/index.ts`. Adding a new data source = new collector + config entry, no other wiring.
- `ProxmoxCollector` (done): one API call to `pve` returns CPU/mem/disk **and PSI pressure**
(`pressurecpusome`, `pressurememoryfull`) for the host + every LXC. Covers ~22 of ~24 machines.
- `SshHostCollector` (done): covers `.180` (omv) and `.171` (ripper), the bare-metal boxes Proxmox
can't see. Dedicated SSH key with a **forced `command=`** in the remote `authorized_keys` — the
server always runs a fixed read-only script regardless of what's exec'd, so a leaked key is still
contained. See `docs/ssh-collector-key-setup.md`, including the gotcha that `diskPaths` in
`hosts.yaml` must be kept in sync **by hand** with the remote script's `DISK_<label>=` lines.
- Everything else (Zabbix alerts) is filed as backlog issues, not yet implemented.
- Auth: local (bcrypt + signed session cookie) is live. `AUTH_MODE=oidc` is a stubbed config value only —
Authentik wiring is issue #12, not implemented.
- **Device discovery** (done, separate from the collector system above — it's inventory, not per-host
metrics): `scripts/discover-devices.sh` runs via systemd timer **on the CT122 host**, not in Docker
(real ARP entries live in the host's network namespace, not Docker's bridge network). API reads the
resulting JSON each poll cycle. Full reasoning in `docs/device-discovery.md`.
## Infrastructure this project owns
- **Gitea repo**: `jhodgkin/homelab-monitor`
- **Proxmox API token**: `monitor@pve!dashboard`, role `PVEAuditor` (read-only), created via `pveum` on
`pve`. Secret lives only in CT122's `.env`.
- **Deployment**: CT122 (`homelab-monitor`, 192.168.1.103), unprivileged LXC on `pve`, Docker + Compose.
SSH alias `homelab-monitor` in `~/.ssh/config` (root, key-based). Not yet exposed externally — see
issue #13 (needs NPM proxy host + Cloudflare tunnel route).
- **SSH collector key**: `monitor_ed25519` keypair lives only at `/opt/homelab-monitor/ssh/` on CT122
(gitignored, not in the repo). Public key installed on `omv` and `ripper` with a forced command —
see `docs/ssh-collector-key-setup.md`.
- **Vaultwarden**: dashboard admin credentials saved as "Homelab Monitor (dashboard admin)".
## Known gaps / explicitly deferred (see issues for detail)
- No historical charts yet — only the latest snapshot is shown (24h retention in SQLite unused by the UI so far).
- No Zabbix/Graylog integration yet — this dashboard doesn't duplicate their alerting, just complements it later.
- Public exposure and Authentik OIDC both need either credentials from the user or manual dashboard steps
(Cloudflare Zero Trust, NPM admin UI, Authentik admin) — flagged in the relevant issues, not blocking.