All screenshots are mock UIs drawn from fake data. Work projects are described without client or employer names.
personal · infrastructure · 2026-09-12
Status page and privacy-first usage analytics for a self-hosted server
It probes 15 services and 3 bots every 30 s using up to five signals each, keeps 90 days of history, and adds first-party analytics that count only active screen time. Zero npm dependencies. Built and deployed on 2026-09-12.
Fifteen services and three bots ran on one box with no view of their health, so an outage was found only by using the thing that had broken. The analytics half answers a separate question: what to build next.
Constraints
Zero npm dependencies. The thing that must stay up when everything else breaks must not depend on an install.
Gated sites answer 401/403/302 to a probe, and these must count as healthy.
The analytics identity is set server-side from the proxy. Any identity in the client body is ignored.
No IPs, no cross-site identifiers, 180-day retention, and the data never leaves the box.
History is written atomically, so a redeploy never destroys it.
What I built
per service, up to 5 signals
systemd unit state --+
Docker state/health -+
loopback /health ----+--> status collector Node 22, empty capability set
raw TCP connect -----+ | 30 s rolling samples
HTTPS via proxy -----+ | 90 days of hourly buckets (atomic JSON)
v
dashboard hand-drawn SVG uptime strips,
latency sparklines, host tiles, drawers
browser beacon --------> analytics collector DynamicUser, node:sqlite
(counts time only while the tab is visible and the user was active in the last ~60 s, monotonic clock)reverse proxy + basic auth = the whole access boundary
strips inbound X-Auth-*, injects identity; both services bind loopback
deploy: idempotent, validates, rolls back
fig 1. Two small services with no dependencies, behind one trust boundary.
Mapped the infrastructure from the live box rather than assuming it.
Built both collectors, the dashboards and the trust boundary (inbound X-Auth-* stripped, identity injected by the proxy).
Wrote an idempotent deploy with validation and rollback.
Outcome
date
result
2026-09-12
Deployed: 18 of 18 checks healthy, certificate issued, 401 without credentials
2026-09-12
A stopped container turned its row red within five seconds
2026-09-12
The first deploy failed on a reverse-proxy log-ownership trap and the existing sites stayed up. Fixed
2026-09-12
Analytics deployed. A real visit was stored with identity attributed server-side