Commit Graph

11 Commits

Author SHA1 Message Date
jhodgkin 27c83d52b2 fix: ProxmoxCollector read wrong shape for node mem/disk
CI / web (push) Successful in 18s
CI / api (push) Successful in 24s
/nodes/{node}/status nests memory/rootfs objects; the LXC listing
endpoint uses flat mem/maxmem/disk/maxdisk. Code assumed the LXC
shape for both, so the Proxmox host's own memPct/diskPct were NaN ->
serialized as null the whole time. Found while checking sparkline
history data looked wrong for the host card specifically.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-12 21:34:10 -06:00
jhodgkin f3ee4c2424 Add historical sparklines to host cards
CI / web (push) Successful in 17s
CI / api (push) Successful in 24s
24h of snapshots were already being retained but never read. Adds a
windowed query (last ~40 samples/host, one query total via
ROW_NUMBER() OVER PARTITION BY, not N+1) embedded in the existing
/api/hosts response, rendered as small hand-rolled SVG sparklines
(cpu/mem/disk overlaid) -- no charting library needed at this scale.

Closes #10.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-12 21:32:36 -06:00
jhodgkin ce232c5a53 Finish public exposure: monitor.jerodrigged.com is live
CI / web (push) Successful in 17s
CI / api (push) Successful in 22s
Cloudflare tunnel route -> NPM -> dashboard, Let's Encrypt cert via
NPM's API, both public and LAN OIDC redirect URIs registered in
Authentik. Hit and fixed a Flexible-SSL redirect loop (ssl_forced
must stay false since Cloudflare terminates TLS at the edge and talks
plain HTTP to the origin) -- documented clearly so it doesn't get
"fixed" by accident later.

Closes #13.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-12 21:27:54 -06:00
jhodgkin 04131006ed docs: record Zabbix decision, CT122 conflict, OIDC/exposure status
CI / web (push) Successful in 18s
CI / api (push) Successful in 24s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-12 21:17:06 -06:00
jhodgkin a431b87f1f Add Authentik OIDC login as an additional sign-in option
CI / web (push) Successful in 19s
CI / api (push) Successful in 28s
Local auth stays the primary/always-available login (don't want to
lock out the saved admin password) — OIDC is additive, shown as a
second button when OIDC_ENABLED=true. Uses openid-client v6 with PKCE.

Authentik-side provider was set up via an authentik blueprint (its own
declarative automation, see docs/oidc-setup.md) rather than touching
any existing admin credentials.

Closes #12.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-12 20:59:25 -06:00
jhodgkin 9891751d37 docs: update CLAUDE.md for device discovery
CI / web (push) Successful in 17s
CI / api (push) Successful in 22s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-12 20:50:50 -06:00
jhodgkin 04282232cc Add LAN device discovery (ping sweep + ARP, known/unknown labeling)
CI / web (push) Successful in 17s
CI / api (push) Successful in 23s
Runs as a host-level systemd timer on CT122 (scripts/discover-devices.sh)
rather than inside the api container, since real ARP entries live in the
host's network namespace, not Docker's bridge network. See
docs/device-discovery.md for the full writeup, including why literal
passive-only ARP reading was dropped (near-empty result in practice).

API reads the resulting JSON file each poll cycle, cross-references
config/hosts.yaml's knownDevices list by IP, and serves /api/devices.
Dashboard gets a new "Network Devices" table.

Closes #9.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-12 20:49:22 -06:00
jhodgkin d75bd58792 docs: update CLAUDE.md for SSH collector + Vaultwarden entry
CI / web (push) Successful in 19s
CI / api (push) Successful in 24s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-12 20:42:05 -06:00
jhodgkin 7df08cd16d Add SshHostCollector for .180 (omv) and .171 (ripper)
CI / web (push) Successful in 20s
CI / api (push) Successful in 27s
Extends monitoring to the two bare-metal boxes Proxmox can't see.
Uses a dedicated ed25519 key with a forced authorized_keys command
(see docs/ssh-collector-key-setup.md) so a leaked key can only ever
run the fixed read-only stats script, never arbitrary commands.

CPU is approximated from 1-min load average / core count (a true
utilization % would need two /proc/stat samples).

Closes #8.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-12 20:40:10 -06:00
jhodgkin ac768ed0db fix: decouple session cookie 'secure' flag from NODE_ENV
CI / web (push) Successful in 16s
CI / api (push) Successful in 17s
Cookie was silently never set because NODE_ENV=production forced
secure=true while the app is served over plain HTTP on the LAN (TLS
terminates at a reverse proxy later, not here). Add explicit
COOKIE_SECURE env var, default false.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-12 20:21:52 -06:00
jhodgkin a075488f4b Scaffold homelab-monitor: Fastify API + React dashboard + CI
CI / web (push) Failing after 1m11s
CI / api (push) Successful in 1m19s
Vertical slice for Phase 1 (v1-dashboard milestone): Proxmox collector,
SQLite storage, local auth, and a dashboard UI showing host/container
status cards. Config-driven collector registry so future data sources
(SSH-based hosts, Zabbix, network discovery) plug in without rewiring.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-12 20:18:44 -06:00