A beautiful, real-time monitoring dashboard for Raspberry Pi home servers.
- Real-time monitoring β CPU, RAM, temperature, disk usage
- Temperature insights β Min/max session tracking, throttling status (via vcgencmd)
- Docker integration β Container stats with CPU/memory usage
- WireGuard VPN β Monitor connected clients, transfer stats, last seen
- Network stats β Bandwidth, connections per interface
- Service health β HTTP, TCP, Redis, DNS health checks
- External API β REST API with key authentication for external apps
- Modern UI β Glassmorphism, smooth animations, dark theme
- Display modes β Normal, Compact, and Ultra-compact layouts
- Multiple themes β 5 color themes (cyan, emerald, rose, amber, indigo)
- Persistent settings β Server-side config, shared across devices
- PWA ready β Install on mobile, works offline
Silicon/AI aesthetic inspired by Apple System Preferences meets Vercel Dashboard:
- Deep dark theme (#0a0a0a)
- Glassmorphism cards
- Cyan/purple accent gradients
- Smooth micro-interactions
- Responsive card-based layout
- Multiple color themes
# Clone
git clone https://github.com/zepgram/pi-dashboard.git
cd pi-dashboard
# Install
npm install
# Run (dev)
npm run devDashboard available at http://localhost:5173
The easiest way β use the pre-built multi-arch image (supports amd64 and arm64):
# Create a directory for your config
mkdir -p pi-dashboard/data && cd pi-dashboard
# Download docker-compose.yml
curl -O https://raw.githubusercontent.com/zepgram/pi-dashboard/main/docker-compose.yml
# Start
docker compose up -dDashboard available at http://your-pi-ip:3001
# Clone
git clone https://github.com/zepgram/pi-dashboard.git
cd pi-dashboard
# Create data directory
mkdir -p data
# Build and start
docker compose up -d --buildservices:
pi-dashboard:
image: usernamedigital/pi-dashboard:latest
# Or build locally:
# build: .
container_name: pi-dashboard
restart: unless-stopped
environment:
- PORT=3001
- ADMIN_TOKEN= # Optional: protect config endpoints
- CORS_ORIGINS=* # Or specific origins
volumes:
# Persistent settings (dashboard config, services, API keys)
- ./data:/app/data
# System monitoring (required)
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/host/root:ro
# Docker container monitoring
- /var/run/docker.sock:/var/run/docker.sock:ro
# WireGuard monitoring (optional)
- /etc/wireguard:/etc/wireguard:ro
# Required for full system access
pid: host
network_mode: host
# Required for WireGuard monitoring
cap_add:
- NET_ADMIN
healthcheck:
test: ["CMD", "wget", "-q", "--spider", "http://localhost:3001/api/health"]
interval: 30s
timeout: 5s
retries: 3| Tag | Description |
|---|---|
latest |
Latest stable release from main branch |
1.0.0 |
Specific version (semver) |
1.0 |
Latest patch for minor version |
1 |
Latest minor for major version |
<sha> |
Specific commit (7 chars) |
| Setting | Purpose |
|---|---|
pid: host |
Access host processes (top processes, accurate CPU stats) |
network_mode: host |
Access host network interfaces, no port mapping needed |
/proc:/host/proc:ro |
Read host CPU, memory, process info |
/sys:/host/sys:ro |
Read host temperature, disk info, cgroups |
/:/host/root:ro |
Read host disk usage, OS info |
/var/run/docker.sock |
Monitor Docker containers |
/etc/wireguard:ro |
Read WireGuard client configs (optional) |
cap_add: NET_ADMIN |
Required for wg show command |
./data:/app/data |
Persist settings & API keys across restarts |
# Using Docker Hub image
docker run -d --name pi-dashboard \
--pid=host \
--network=host \
--cap-add=NET_ADMIN \
-v $(pwd)/data:/app/data \
-v /proc:/host/proc:ro \
-v /sys:/host/sys:ro \
-v /:/host/root:ro \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
-v /etc/wireguard:/etc/wireguard:ro \
usernamedigital/pi-dashboard:latest
# Or build locally
docker build -t pi-dashboard .
docker run -d --name pi-dashboard \
--pid=host \
--network=host \
--cap-add=NET_ADMIN \
-v $(pwd)/data:/app/data \
-v /proc:/host/proc:ro \
-v /sys:/host/sys:ro \
-v /:/host/root:ro \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
-v /etc/wireguard:/etc/wireguard:ro \
pi-dashboardβββ server/
β βββ index.js # Express API
β βββ stats.js # System stats collector
βββ src/
β βββ index.html
β βββ main.js
β βββ style.css
βββ data/
β βββ settings.json # Persistent config (mount as volume)
βββ Dockerfile
βββ package.json
βββ vite.config.js
All settings are stored in settings.json β both dashboard preferences and services:
{
"dashboard": {
"theme": "default",
"interval": 2,
"sound": true,
"compact": false,
"thresholds": {
"cpu": { "warning": 70, "critical": 90 },
"memory": { "warning": 80, "critical": 95 },
"temperature": { "warning": 65, "critical": 80 }
}
},
"api": {
"enabled": false,
"keyHash": null
},
"services": [
{
"name": "Pi-hole Admin",
"port": 80,
"path": "/admin/",
"host": "localhost",
"checkType": "http",
"icon": "shield",
"enabled": true
},
{
"name": "Nextcloud",
"port": 8080,
"path": "/",
"checkType": "http",
"icon": "cloud",
"enabled": true
}
]
}| Field | Description | Default |
|---|---|---|
theme |
Color theme (default, emerald, rose, amber, indigo) | default |
interval |
Refresh interval in seconds | 2 |
sound |
Enable alert sounds | true |
compact |
Compact display mode | false |
thresholds |
Warning/critical thresholds | see above |
| Field | Description | Default |
|---|---|---|
name |
Display name | required |
port |
Service port | required |
path |
Health check path | / |
host |
Hostname | localhost |
enabled |
Show in dashboard | true |
| Endpoint | Method | Description |
|---|---|---|
/api/stats |
GET | CPU, RAM, temp, containers, disks |
/api/settings |
GET | Dashboard settings |
/api/settings |
PUT | Update dashboard settings |
/api/settings/api |
GET | API access settings |
/api/settings/api |
PUT | Enable/disable API, generate key |
/api/services |
GET | Service health status |
/api/services/config |
GET | Get all services config |
/api/services/config |
PUT | Update all services |
/api/services/config |
POST | Add a service |
/api/services/config/:index |
DELETE | Remove a service |
/api/services/discover |
GET | Auto-discover services on listening ports |
/api/sysinfo |
GET | System information |
/api/health |
GET | Dashboard health check |
/api/wireguard |
GET | WireGuard clients status |
/api/settings/wireguard |
GET | WireGuard settings (enabled, interface) |
/api/settings/wireguard |
PUT | Update WireGuard settings |
Public API for external applications, protected by API key.
| Endpoint | Method | Description |
|---|---|---|
/api/v1/system |
GET | Complete system data (stats + sysinfo + wireguard if enabled) |
Authentication: Enable API access and generate a key via the dashboard UI (API button in header).
# Using header
curl -H "X-API-Key: YOUR_KEY" http://your-pi:3001/api/v1/system
# Using query param
curl "http://your-pi:3001/api/v1/system?key=YOUR_KEY"Response includes:
systemβ manufacturer, model, serialcpuβ usage, cores, speed, brandmemoryβ total, used, free, percent, type (e.g., LPDDR4X)temperatureβ main, max, throttled (bitmask from vcgencmd)loadβ uptime, loadAvg [1m, 5m, 15m]osβ distro, version, kernel, hostname, archdisksβ mount points with size/used/availablenetworkβ interfaces (IP, type) + stats (rx/tx bytes/sec)containersβ Docker containers with CPU/memory statsprocessesβ Top 10 processes by CPU usagebaseboardβ hardware infoservicesβ configured services with health status (online/offline, latency)wireguardβ (if enabled) interface name + clients array with name, publicKey, endpoint, lastHandshake, transfer, online status
Security: API keys are hashed (SHA256) before storage. The plain key is shown only once at generation β copy it immediately or regenerate.
Configure via docker-compose.yml or environment variables:
| Variable | Description | Default |
|---|---|---|
ADMIN_TOKEN |
Auth token for config endpoints | (empty = no auth) |
CORS_ORIGINS |
Allowed origins (comma-separated) | * |
PORT |
Server port | 3001 |
When ADMIN_TOKEN is set, config write operations require the header:
X-Admin-Token: your-secret-token-here
Security features:
- Input validation & sanitization
- XSS protection
- Rate limiting (100 req/min on config endpoints)
- CORS origin restrictions
- Payload size limits
- Node.js 22+
- Raspberry Pi (ARM64) or any Linux server
- Docker (optional, for container monitoring)
Pi Dashboard reads container CPU from cgroups v2 (/sys/fs/cgroup/.../cpu.stat) and memory from /proc/[PID]/status. Works without enabling the memory cgroup controller β no kernel modifications needed!
CPU usage is normalized to 100% (total CPU capacity), not per-core.
- Persistent server-side settings
- Container CPU/memory stats
- Smooth animations
- Auto-discover services
- External REST API with key auth
- Multiple color themes
- Mobile-friendly UI
- WireGuard VPN monitoring
- Temperature min/max + throttling status
- Display modes (normal/compact/ultra)
- Historical charts (last hour/day)
- Log viewer
- Multi-server support
MIT β do whatever you want with it.
Built with β on a Raspberry Pi 5