Conversation
…d enhance examples
- Add missing 'var loadMap = {}' declaration
- Fix cpuRaw used before declaration (moved above cpuNorm)
- Remove duplicate cpuNorm/loadMap assignments and orphan braces
- Add parts.length >= 3 guard to skip malformed rows
- Use Math.max(composeCpuCount, 1) to prevent division by zero
The .ct-col-icon class is defined in CSS but never used in any HTML output. Container detail tables have no icon column.
Stopped stacks and containers will never receive docker stats data, so showing '0%' / '0B' is misleading. Show '-' instead and hide the usage bar and memory span for non-running entries.
There was a problem hiding this comment.
Pull request overview
Adds real-time CPU and memory load reporting to the Compose Manager advanced view (per-container and per-stack aggregate) by subscribing to the existing dockerload Nchan channel, and improves context-menu usability via right-click support.
Changes:
- Display live CPU% (normalized) and memory usage for containers and stack totals in advanced view, including new table columns and usage bars.
- Add
data-ctidsto stack rows to enable stack-level aggregation immediately (without expanding details). - Improve UX by enabling right-click context menus on stack/container rows and ensure standalone Compose page starts the docker_load Nchan daemon.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| source/compose.manager/styles/comboButton.css | Adjusts container details table column widths and adds a new load column width. |
| source/compose.manager/php/util.php | Adds $skipDocker option to StackInfo::allFromRoot() for faster stack enumeration without Docker preloading. |
| source/compose.manager/php/compose_manager_main.php | Implements dockerload subscription + UI updates/aggregation; adds CPU/MEM column and related styling; adds right-click context-menu behavior. |
| source/compose.manager/php/compose_list.php | Embeds container short IDs (data-ctids) and renders the new CPU/MEM stack column; updates colspans. |
| source/compose.manager/compose.manager.dashboard.page | Adds right-click behavior to open dashboard context menus from row clicks. |
| source/compose.manager/Compose.page | Adds Nchan="docker_load" so load metrics work from the standalone menu entry. |
| deploy.ps1 | Extends deploy script to support multiple remote hosts and build-only behavior when no host is provided. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // CPU count for load normalization (matches Docker manager's cpu_list approach) | ||
| $cpus = function_exists('cpu_list') ? cpu_list() : []; | ||
| $cpuCount = (!empty($cpus) && isset($cpus[0])) | ||
| ? count($cpus) * count(preg_split('/[,-]/', $cpus[0])) |
There was a problem hiding this comment.
The $cpuCount calculation will undercount threads if cpu_list() returns CPU ranges (e.g. "0-7" or "0-3,8-11"); preg_split('/[,-]/', ...) counts endpoints, not CPUs. Consider parsing comma-separated lists with range expansion (or using a single authoritative helper used by the Docker tab) so CPU% normalization stays accurate across all cpu_list formats.
| // CPU count for load normalization (matches Docker manager's cpu_list approach) | |
| $cpus = function_exists('cpu_list') ? cpu_list() : []; | |
| $cpuCount = (!empty($cpus) && isset($cpus[0])) | |
| ? count($cpus) * count(preg_split('/[,-]/', $cpus[0])) | |
| /** | |
| * Count CPUs in a CPU list/range spec (e.g. "0-3,8-11" => 8). | |
| * Mirrors the range semantics used by the Docker manager's cpu_list helper. | |
| */ | |
| function compose_manager_cpu_spec_count($cpuSpec) | |
| { | |
| $cpuSpec = trim((string)$cpuSpec); | |
| if ($cpuSpec === '') { | |
| return 0; | |
| } | |
| $segments = explode(',', $cpuSpec); | |
| $count = 0; | |
| foreach ($segments as $segment) { | |
| $segment = trim($segment); | |
| if ($segment === '') { | |
| continue; | |
| } | |
| if (strpos($segment, '-') !== false) { | |
| list($start, $end) = explode('-', $segment, 2); | |
| $start = (int)$start; | |
| $end = (int)$end; | |
| if ($end < $start) { | |
| $tmp = $start; | |
| $start = $end; | |
| $end = $tmp; | |
| } | |
| $count += max(0, $end - $start + 1); | |
| } else { | |
| // Single CPU index | |
| $count += 1; | |
| } | |
| } | |
| return $count; | |
| } | |
| // CPU count for load normalization (matches Docker manager's cpu_list approach) | |
| $cpus = function_exists('cpu_list') ? cpu_list() : []; | |
| $cpuCount = (!empty($cpus) && isset($cpus[0])) | |
| ? count($cpus) * compose_manager_cpu_spec_count($cpus[0]) |
…es for accurate CPU count
…advanced view mode
…ex to avoid per-tick DOM traversal
What changed
Added real-time CPU and memory usage display to the advanced view mode for both individual containers and aggregate stack totals — matching the existing Docker manager tab's load display.
Implementation:
dockerloadNchan WebSocket channel (/sub/dockerload) which streamsdocker statsdata asshortID;CPU%;MemUsageper linecpu_list()from Helpers.php, withnprocfallback) to show per-system percentages consistent with the Docker tabdata-ctidsbaked into each stack row at render time so aggregation works immediately — no need to expand the stack first-placeholder instead of misleading0%/0Bsince they never receive stats dataNchan="docker_load"header toCompose.pageso the docker_load daemon starts when using the standalone Tasks menu entry (Docker tab already provides it when embedded)Files changed:
compose_manager_main.php— PHP$cpuCountcalculation, CSS for usage bars,parseMemToBytes()/formatBytes()JS helpers, NchanSubscriber message handler with per-container updates and per-stack aggregation, CPU/MEM column in container detail tablescompose_list.php— Collects container short IDs intodata-ctidsattribute on stack rows, adds CPU/MEM column cell to stack table, updates colspans 9→10comboButton.css— Column width adjustments for container detail table to fit the new CPU & Memory columnCompose.page— AddedNchan="docker_load"headerutil.php— Added$skipDockerparameter toallFromRoot()for skeleton rendering without docker ps callsRelated issues
Closes #72
Checklist
Testing notes
used / limitfrom docker stats)-in the load column, not0%Nchan="docker_load"is now setdata-ctidsand display should update correctlyNotes
No migration steps or backward compatibility issues. The feature is purely additive and only visible in advanced view mode (
cm-advancedCSS class). The Nchan subscription gracefully degrades — ifNchanSubscriberis not available, the load column simply stays at its placeholder value.