DocHub
Architecture and purpose of the OVH5 monitoring dashboard

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-attach and 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 .tmp then mv to 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 /data partitions
  • 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