5.4 KiB
Cockpit NVIDIA GPU Dashboard
Custom Cockpit package that displays live GPU stats (model, driver, CUDA version, temperature, utilization, memory, processes) in the web UI sidebar on port 9090.
When to use
- User wants GPU temperature / utilization / memory visible in Cockpit
- User prefers a web UI over terminal
nvidia-smiornvtop
Two approaches
cockpit.script() (run nvidia-smi directly) silently fails on some Cockpit
versions (Ubuntu 26+, Cockpit ~314+). The systemd + file-read approach
is more reliable and preferred.
Approach A (recommended): systemd service + file-read
Write GPU data to files periodically via a background service, then read them
from the Cockpit page with cockpit.file().read(). Avoids all PATH and
permission issues with running nvidia-smi from the Cockpit bridge.
1. Create the data-collection script
/usr/local/bin/nvidia-gpu-monitor.sh:
#!/bin/bash
while true; do
nvidia-smi --query-gpu=name,driver_version,temperature.gpu,utilization.gpu,memory.used,memory.total,power.draw,pstate,fan.speed --format=csv,noheader,nounits 2>/dev/null | head -1 > /run/nvidia-gpu.txt
nvidia-smi --query-compute-apps=pid,process_name,used_memory --format=csv,noheader,nounits 2>/dev/null > /run/nvidia-processes.txt
nvidia-smi 2>/dev/null | grep "CUDA Version" | sed 's/.*CUDA Version: //' | head -1 > /run/nvidia-cuda.txt
sleep 5
done
Make executable: sudo chmod +x /usr/local/bin/nvidia-gpu-monitor.sh
2. Create systemd service
/etc/systemd/system/nvidia-gpu-monitor.service:
[Unit]
Description=NVIDIA GPU Monitor - writes stats to /run
After=nvidia-persistenced.service
[Service]
Type=simple
ExecStart=/usr/local/bin/nvidia-gpu-monitor.sh
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target
Enable and start:
sudo systemctl daemon-reload
sudo systemctl enable --now nvidia-gpu-monitor
3. Create the Cockpit package
/usr/share/cockpit/nvidia-gpu/manifest.json:
{
"version": 1,
"requires": { "cockpit": "260" },
"menu": {
"index": { "label": "NVIDIA GPU", "order": 90 }
},
"content-security-policy": "default-src 'self'; script-src 'unsafe-inline'"
}
/usr/share/cockpit/nvidia-gpu/index.html:
The page uses cockpit.file(path).read() to read /run/nvidia-gpu.txt,
/run/nvidia-processes.txt, and /run/nvidia-cuda.txt. Each file contains
a single line of comma-separated values written by the systemd service.
Key implementation:
function readFile(path) { return cockpit.file(path).read(); }
function update() {
readFile('/run/nvidia-gpu.txt').done(function(data) {
if (!data || !data.trim()) { /* show error */ return; }
var parts = data.trim().split(', ');
// parts[0] = name, [1] = driver, [2] = temp, [3] = util,
// [4] = mem_used, [5] = mem_total, [6] = power, [7] = pstate, [8] = fan
// ... render cards ...
});
readFile('/run/nvidia-cuda.txt').done(function(d) { /* show CUDA version */ });
readFile('/run/nvidia-processes.txt').done(function(d) { /* render process table */ });
}
setInterval(update, 5000);
4. Install and restart Cockpit
sudo mkdir -p /usr/share/cockpit/nvidia-gpu
# Write manifest.json and index.html (use sudo tee or sudo cp)
sudo chmod 644 /usr/share/cockpit/nvidia-gpu/*
sudo systemctl restart cockpit
5. Verify
- Open
https://<server>:9090in browser - Log in with server credentials
- Click NVIDIA GPU in sidebar — live metrics refresh every 5s
Approach B (fallback): cockpit.script() directly
Use when Approach A isn't practical (no systemd, containerized Cockpit, etc.):
cockpit.script("/usr/bin/nvidia-smi --query-gpu=... --format=csv,noheader,nounits", null, {superuser: 'try'})
.done(function(data) { /* parse and render */ })
.fail(function(err) { /* show error */ });
Caveats (why Approach A is preferred):
cockpit.script()may silently hang on Cockpit v314+ (Ubuntu 26+)- PATH may not include
/usr/bin/in non-interactive bridge sessions - The
.fail()handler may catch but not always fire for certain errors - Debugging is harder — the error object from Cockpit bridge is opaque
If using this approach, use the full path /usr/bin/nvidia-smi and avoid
{superuser: 'try'} unless nvidia-smi requires root on the target system.
Troubleshooting
| Symptom | Likely Cause | Fix |
|---|---|---|
| "No NVIDIA GPU detected" | Can't read data files or run nvidia-smi | Check /run/nvidia-gpu.txt exists and is populated. Restart service: sudo systemctl restart nvidia-gpu-monitor |
| Page shows stale data | systemd service stopped or crashed | sudo systemctl status nvidia-gpu-monitor — restart if dead |
Power shows [N/A] |
GTX 1050 Ti doesn't report power draw | Normal — handle gracefully in display |
| Page loads blank | CSP blocking inline script | Add 'unsafe-inline' to manifest CSP |
| "No GPU processes" when Immich is processing | Jobs may be between batches | Check nvidia-smi directly — should show python process |
| Ctrl+Shift+R needed after updates | Cockpit aggressively caches package content | Hard-refresh or open in private/incognito tab |
Related
- Install
nvtopfor terminal TUI monitor:apt install nvtop(or build from https://github.com/Syllo/nvtop) - GPU acceleration setup: see the parent
docker-gpu-accelerationskill