Phase 15: dashboard stack resource usage (0.16.0)

The dashboard now lists stacks in a table with live CPU and memory usage per
stack. Usage is sampled from docker stats (one-shot read per running container,
using the daemon-provided precpu for the CPU delta) and aggregated by compose
project.

- services/stats_service.py + GET /api/stacks/stats: per-stack cpu_used (cores),
  mem_used (bytes minus reclaimable cache), and the summed assigned cpu/mem
  limits (null when none set), read concurrently across containers.
- Dashboard: stacks render as a table with a CPU and a Memory meter. When a
  limit is assigned the bar fills toward it (used / limit + %); otherwise it
  fills toward the host total. Inline start/stop/restart per row for admins.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
menzelj
2026-06-08 12:20:52 +00:00
co-authored by Claude Opus 4.8
parent c5f591749f
commit 19cc92dc94
9 changed files with 338 additions and 24 deletions
+7 -1
View File
@@ -26,7 +26,7 @@ from models.setting import (
EVENT_STACK_STOP,
)
from models.user import User
from services import audit_service, compose_service, notify_service
from services import audit_service, compose_service, notify_service, stats_service
from services.convert_service import convert_docker_run
router = APIRouter(prefix="/api/stacks", tags=["stacks"])
@@ -116,6 +116,12 @@ def create_stack(
return _stack_summary(stack)
@router.get("/stats")
def stacks_stats(_user: User = Depends(get_current_user)) -> dict:
"""Live CPU (cores) and memory usage per stack, with assigned limits."""
return stats_service.stack_stats()
@router.get("/{stack_id}")
def get_stack(
stack_id: str,