Dashboard Overview
Purpose
Real-time monitoring dashboard for the OVH5 dev server (15.204.90.153) and its 5 LXC containers. Provides at-a-glance visibility into container health, Claude Code usage, Docker status, and system resources.
URL: https://admin.ipnoelp.io
Deployed: 2026-02-28
Architecture
Two systemd-driven collector scripts gather metrics and write atomic JSON files. A zero-dependency Node.js server reads the JSON and serves a single-page dashboard through nginx.
[systemd timer: 30s] → collect-dashboard.sh → /tmp/dashboard-status.json
[systemd timer: 5m] → collect-dashboard-slow.sh → /tmp/dashboard-status-slow.json
↓
[browser] ← [Cloudflare Access] ← [nginx :443] ← [Node.js :3580] ← reads JSON
Design Principles
- Collectors run as root — needed for
lxc-attachand cgroup reads - Node.js runs unprivileged (user
ubuntu) — reads pre-collected JSON only - Zero npm dependencies — uses only built-in Node.js modules
- Atomic writes — collectors write to
.tmpthenmvto prevent partial reads - Cloudflare Access for authentication (same policy as term.ipnoelp.com)
What Gets Monitored
Host Level (every 30 seconds)
- CPU load (1/5/15 min averages) and core count
- Memory used vs available
- Disk usage for
/and/datapartitions - Service status: nginx, claude-net-tunnel, fail2ban
- Fail2ban banned IP count and detailed list
Per Container (every 30 seconds)
- State (running/stopped), IP address
- CPU load, memory (from host cgroup — accurate for containers)
- Network TX/RX bytes, uptime
- Claude Code process detection (running/PID)
- tmux session status
- Docker containers (names, images, status)
- Last 10 SSH sessions with IP, date, and duration
Per Container — Slow (every 5 minutes)
- Disk usage (rootfs size via
du -sb) - Claude Code version
- Token usage from JSONL session files (today’s total output tokens)
- Snapshot age and status
Security Model
| Layer | Implementation |
|---|---|
| Authentication | Cloudflare Access — @omelasai.com only (planned) |
| SSL | Self-signed cert on nginx, Cloudflare terminates public SSL |
| Node.js binding | 127.0.0.1 only — not directly accessible |
| Sudoers | Minimal — ubuntu can only run fail2ban-client status sshd |
| API key storage | Admin API key in /opt/dashboard/.env, not in code |