Files
OpenClaw Coder 8289bc85e8 Add ServerDash: self-hosted Docker & host monitoring dashboard
- Flask backend + static SPA (HTML/CSS/JS)
- Docker container discovery via unix socket (stdlib only, no docker SDK)
- Host stats (CPU/mem/disk/load/uptime) via psutil
- Live-updating UI with per-state filters and resource gauges
- Dockerfile for containerized deployment
2026-11-11 00:15:58 +10:00

76 lines
3.5 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>ServerDash — Docker &amp; Host Monitor</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}" />
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><text y='14' font-size='14'>📊</text></svg>" />
</head>
<body>
<header class="topbar">
<div class="brand">
<span class="brand-icon">📊</span>
<span class="brand-name">ServerDash</span>
<span class="brand-sub">Docker &amp; Host Monitor</span>
</div>
<div class="topbar-status">
<span id="host-badge" class="badge badge-idle">host …</span>
<span id="last-update" class="muted">updating …</span>
<button id="refresh-btn" class="btn" title="Refresh now">⟳ Refresh</button>
</div>
</header>
<main>
<!-- Host summary cards -->
<section class="cards" id="host-cards" aria-label="Host stats">
<div class="card" data-metric="cpu">
<div class="card-label">CPU</div>
<div class="card-value"><span class="num" id="cpu-pct">–</span><span class="pct">%</span></div>
<div class="card-detail" id="cpu-detail">–</div>
</div>
<div class="card" data-metric="memory">
<div class="card-label">Memory</div>
<div class="card-value"><span class="num" id="mem-pct">–</span><span class="pct">%</span></div>
<div class="card-detail" id="mem-detail">–</div>
</div>
<div class="card" data-metric="disk">
<div class="card-label">Disk</div>
<div class="card-value"><span class="num" id="disk-pct">–</span><span class="pct">%</span></div>
<div class="card-detail" id="disk-detail">–</div>
</div>
<div class="card" data-metric="load">
<div class="card-label">Load avg</div>
<div class="card-value"><span class="num" id="load-1">–</span></div>
<div class="card-detail" id="load-detail">–</div>
</div>
<div class="card" data-metric="uptime">
<div class="card-label">Uptime</div>
<div class="card-value"><span class="num" id="uptime">–</span></div>
<div class="card-detail" id="boot-detail">–</div>
</div>
</section>
<!-- Container summary pills -->
<section class="summary-row">
<button class="pill" data-filter="all">All <span class="pill-count" id="c-all">0</span></button>
<button class="pill pill-running" data-filter="running">Running <span class="pill-count" id="c-running">0</span></button>
<button class="pill pill-starting" data-filter="starting">Starting <span class="pill-count" id="c-starting">0</span></button>
<button class="pill pill-paused" data-filter="paused">Paused <span class="pill-count" id="c-paused">0</span></button>
<button class="pill pill-stopped" data-filter="stopped">Stopped <span class="pill-count" id="c-stopped">0</span></button>
<button class="pill pill-dead" data-filter="dead">Dead <span class="pill-count" id="c-dead">0</span></button>
</section>
<!-- Container grid -->
<section class="grid" id="container-grid" aria-label="Containers"></section>
<footer class="footer">
<span id="container-count">0 containers</span> · auto-refresh <span id="refresh-interval">3s</span>
</footer>
</main>
<script src="{{ url_for('static', filename='js/app.js') }}"></script>
</body>
</html>