All apps · 0 apps
homelabdash
Docker app from Xiaodoudou's Repository
Overview
Readme
View on GitHubhomelabdash
A self-hosted dashboard for your homelab, where every tile comes from a small Node.js plugin
You list your services in one YAML file and homelabdash keeps a page of live numbers about them: what Plex is playing, what the arrs are missing, how full the array is, what the router is pushing. Each service is read by a plugin, and a plugin is one JavaScript file you can write in an afternoon, or ask a coding agent to write.

The server polls each service on its own interval and pushes what changed to the page over a WebSocket, so nothing on screen waits for a reload, and a service is fetched once however many tiles show it. Logins, API keys, SSH, Docker events, cron jobs and buttons such as "pause downloads" all live inside the plugin, so you don't need helper scripts, extra containers or a crontab to feed the page. Keys and passwords never leave the server.
Try it in five minutes
For a quick look you need Node.js 24 and git. The showcase runs against fake services, so you don't need any of them:
git clone https://github.com/xiaodoudou/homelabdash.git
cd homelabdash
npm install
npm run dev:showcase
Open http://localhost:3000 and you get the page from the screenshot, fed by dev/mock-upstreams.js; the graphs fill in over the first few minutes.
To run it for real, use the image:
mkdir -p config data
docker run -d --name homelabdash -p 3000:3000 --user "$(id -u):$(id -g)" \
-v "$PWD/config:/config" -v "$PWD/data:/data" \
xiaodoudoufr/homelabdash:latest
On first start it writes a starter config/homelabdash.yaml, and the page follows every save you make to it. Deploying covers docker compose, Unraid, the Docker socket and reverse proxies.
Your first tiles
A source is the connection to one service, and a tile shows one view of it.
settings:
title: Homelab
sources:
nas:
plugin: unraid
config: { url: http://tower.example, apiKey: "${secret:UNRAID_API_KEY}" }
docker:
plugin: docker
sections:
- { title: Alerts, source: alerts, placement: top }
- title: Server
tiles:
- { title: CPU, icon: mdi:cpu-64-bit, source: nas, options: { metric: cpu }, graph: true }
- { title: Array, icon: mdi:harddisk, source: nas, options: { metric: array } }
- { title: Jellyfin, icon: si:jellyfin, href: http://media.example, container: jellyfin }
The API key goes in config/secrets.yaml as UNRAID_API_KEY: ... and never reaches the browser. homelabdash validate (or docker exec homelabdash homelabdash validate) checks the whole folder and prints each problem as file:line path: message. A typo won't take the page down either: the last good config keeps running and the page shows what's wrong.
Concepts explains sources, tiles, groups, merged cards and graphs. The config reference has every key, and a table for moving over from gethomepage.
Plugins
| Plugin | What it shows |
|---|---|
| adguard | Queries, blocked and filtered counts (today or over the retention), latency, top blocked domains |
| apcupsd | UPS status, load, battery and runtime; alerts when on battery |
| arr | Missing items, queue and health of Radarr, Sonarr, Lidarr or Readarr |
| docker | Container states kept live by Docker events, status dots, disk usage, optional start and stop |
| glances | CPU, memory, load, GPU, sensors, disks and uptime |
| http-json | Any JSON API, several requests merged, JSONata for values |
| mihomo | Current proxy node, connections and live traffic of mihomo (Clash Meta) |
| npm | Nginx Proxy Manager hosts and certificates about to expire |
| openwrt | WAN uptime, address and traffic, conntrack, load and memory over ubus |
| qbittorrent | Leeching and seeding, speeds, active torrents, torrents in error |
| sabnzbd | Rate, queue and time left, optional pause and resume |
| seerr | Pending requests and open issues of Overseerr, Jellyseerr or Seerr |
| ssh | Commands run over SSH on a schedule, and a live log tail |
| sub-quota | Traffic used and expiry of proxy subscriptions |
| tautulli | Plex streams playing now, with a live countdown |
| unraid | CPU, memory, array, pools, uptime, notifications as alerts |
Each plugin's folder has a README with its options, and the plugin list says which ones raise alerts or offer buttons.
Your own plugins
A plugin is a folder with an index.js. It declares what it needs to connect and what a tile can show (both as JSON Schema), fetches data through ctx.http, ctx.ssh and friends, and turns that data into views the page already knows how to draw, without any frontend code.
homelabdash plugin new speedtest # scaffold in config/plugins/speedtest, hot-reloaded
homelabdash plugin run speedtest # what it renders, from recorded responses
homelabdash plugin test speedtest # the contract check and its own tests
Writing a plugin walks through it. The repository is also a Claude Code plugin marketplace: /plugin marketplace add xiaodoudou/homelabdash installs three skills to write plugins, edit the config and deploy. AGENTS.md describes the codebase for any coding agent.
Before you put it on the network
There's no login by default. Before anything you don't trust can reach the dashboard, either keep it to local addresses (with a VPN when you're away) or put it behind an identity proxy such as Authentik or Authelia. SECURITY.md explains both and Deploying has the configs. Behind a reverse proxy, remember the page needs its WebSocket at /api/ws.
Buttons that change something upstream, such as pausing SABnzbd or approving a request, stay hidden until you turn them on for that source. Archiving an Unraid notification is the exception: it's on by default, and notifications.archive: false turns it off.
Documentation
docs/README.md is the map. A few places to start:
- Getting started and Concepts
- Config reference, Views and formats, HTTP and WebSocket API, CLI
- Deploying and Troubleshooting
Contributing, security, license
CONTRIBUTING.md explains how to run the project, test it and send a change. Security problems go through private reporting, see SECURITY.md, and what changed between versions is in CHANGELOG.md.
homelabdash is released under the Apache License 2.0.
Media gallery
1 / 3Requirements
Download Statistics
Related apps
Explore more like this
Explore allDetails
xiaodoudoufr/homelabdash:latestRuntime arguments
- Web UI
http://[IP]:[PORT:3000]/- Network
bridge- Shell
sh- Privileged
- false
- Extra Params
--user 99:100 --group-add 281
Template configuration
Port of the dashboard.
- Target
- 3000
- Default
- 3000
- Value
- 3000
What you edit: homelabdash.yaml, secrets.yaml, and your own plugins, icons and custom.css.
- Target
- /config
- Default
- /mnt/user/appdata/homelabdash
- Value
- /mnt/user/appdata/homelabdash
What the dashboard writes itself: dismissed alerts, plugin state, graph history and cached icons.
- Target
- /data
- Default
- /mnt/user/appdata/homelabdash/data
- Value
- /mnt/user/appdata/homelabdash/data
Only needed by the docker plugin, for container status and events.
- Target
- /var/run/docker.sock
- Default
- /var/run/docker.sock
- Value
- /var/run/docker.sock
Time zone for the clock and job schedules, such as Europe/Paris.
- Default
- Etc/UTC
- Value
- Etc/UTC