- 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
76 lines
3.5 KiB
HTML
76 lines
3.5 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||
<title>ServerDash — Docker & 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 & 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>
|