Lab Dash: a self-hosted homelab homepage with a Docker socket and a privileged container
An open-source dashboard designed to manage your server/homelab applications and services.
At a glance
- What is it?
- Lab Dash is a TypeScript dashboard for homelab services, distributed as a Docker image under GPL-3.0. The compelling part is the widget grid and local-only data model; the part to think hard about is that the documented compose file mounts the Docker socket and runs the container privileged.
- Who is it for?
- Adopt Lab Dash if you already run Docker Compose on a single homelab host, want one internally hosted page for shortcuts and service health, and are comfortable reviewing what a privileged container with the Docker socket can do on that host. Do not adopt it if you need multi-host aggregation, or if your threat model treats the dashboard as a lower-trust surface than the services it monitors.
- Can I use it commercially?
- Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 57 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The homelab bookmark problem Lab Dash is aimed at
Anyone running more than a handful of self-hosted services ends up with a browser bookmarks folder that has stopped being useful. Jellyfin is on one port, Radarr and Sonarr on others, a metrics endpoint somewhere else, and the host itself has no single page that says whether any of it is up. Lab Dash targets exactly that gap. The README describes it as "an open-source user interface designed to be your internally hosted homepage for your homelab/server," and the feature list is a grid of widgets: shortcuts to tools and services, system information, service health checks, and custom widgets. The repository topics name the intended neighbours directly (jellyfin, plex, radarr, sonarr), so the audience is the person who already runs those containers. It is not a monitoring system in the Prometheus sense and it is not a reverse proxy. It is the front door, and it assumes you have already built the house.
How the widget grid and local data model fit together
The README is explicit about the customization surface: drag and reorder widgets, change the background image, add custom search providers, set a custom title and tab name. That is a client-side layout plus a persisted configuration, and the project states where the configuration lives. "All data is stored & used on your own device," and sensitive values are encrypted locally with AES-256-CBC. The encryption key is supplied by you through the SECRET environment variable, and the README suggests generating one with openssl rand -base64 32. Access control is coarse by design: "Only administrator accounts can make changes," which implies a read-only view for everyone else on the LAN. The compose file also mounts /sys read-only and /var/run/docker.sock, which is how the system information and service health widgets get their data. That is the whole architecture as documented: a Node/TypeScript app in one container, reading host and Docker state through mounts, writing config and uploads to two bind mounts, encrypting secrets with a key you provide.
What the documented docker compose file actually grants
The installation section states that only Docker is required, then gives a compose service named lab-dash using the image ghcr.io/anthonygress/lab-dash:latest. Three lines deserve attention before you copy it. First, privileged: true. Second, the volume mount /var/run/docker.sock:/var/run/docker.sock. Third, /sys:/sys:ro. A container with the Docker socket can talk to the Docker daemon, and a privileged container has broad access to the host. The README does not explain which feature needs privileged mode or why the socket is mounted, and it does not offer a reduced-privilege variant. The socket mount is plausibly what feeds service health and container state; the privileged flag is not justified anywhere in the supplied material. The commented-out network_mode: host line is annotated as being "for monitoring network usage stats," with a note to run sudo ufw allow 2022/tcp on Ubuntu if you enable it. The port mapping is 2022:2022, and the app is reachable at http://localhost:2022, at 192.168.x.x:2022 on the LAN, or through a custom domain. The README also tells you to assign the server a static IP so LAN and WAN devices can reach it, which is a hint that exposing this beyond the LAN is a supported pattern rather than an edge case.
Getting it running, and the update path you are signing up for
The documented path is short. Install Docker, copy the compose file or paste the service into an existing one, then run docker compose up -d from the directory containing the YAML. The README notes the container restarts automatically after reboots "unless it was manually stopped," and that stopping it is docker compose down from the same directory. The volumes to review are /docker/lab-dash/config:/config and /docker/lab-dash/uploads:/app/public/uploads, plus the read-only /sys mount and the socket. For local development the README gives npm install then npm run dev. Updating has two documented routes. In Portainer: open the lab-dash stack, click the Editor tab, click Update the stack, enable the re-pull image and redeploy toggle, then click Update. From the CLI: cd into the compose directory, then docker compose down, docker compose pull, docker compose up -d. Note that the image tag is latest, so there is no pinned version to hold you back if an update breaks a widget. The release history shows v1.3.8, v1.3.7 and v1.3.6 as the most recent tags, so versioned tags do exist if you would rather pin one than track latest.
Where Lab Dash is the wrong tool
The honest limitation is the privilege posture, and it is not a small one. If your threat model treats the dashboard as a lower-trust surface than the services it links to, then a privileged container with the Docker socket mounted inverts that: compromising the dashboard is roughly equivalent to compromising the host. The README does not address this, does not document a socketless mode, and does not explain what breaks if you drop privileged: true. That is a gap you have to close yourself, by experiment, before you trust it. The second limitation is that the documentation is thin on the health-check mechanism. The feature list says "service health checks" but the supplied material does not say whether checks are HTTP requests, TCP connects, or Docker state reads, what interval they run at, or what happens when a check fails. You cannot size the load it puts on your services from the README alone. Third, this is a single-host tool. Nothing in the material suggests agents, remote hosts, or federation, so a two-machine setup means two dashboards. Finally, the README carries a disclaimer that the code is "for informational and educational purposes only," which is boilerplate but worth reading as a signal that the author is not offering support guarantees.
Homepage versus Lab Dash: config file against live host state
The closest well-known alternative in this space is Homepage (gethomepage), which the repository topics implicitly acknowledge by listing "homepage" alongside dashboard and self-hosted. The difference in approach is where the truth lives. Homepage is configured through YAML service definitions and widget declarations that you commit alongside your compose files; the page is a rendering of a config file you own and can diff. Lab Dash, as documented, is configured through the UI itself, with drag-and-drop ordering and settings persisted to the /config volume and sensitive values encrypted with your SECRET key. That means no YAML to review in a pull request, but also no plain-text record of your layout unless you back up the volume. Lab Dash's system information and service health widgets pull live host and Docker state through /sys and the Docker socket, which is a different kind of data than Homepage's widget integrations typically surface. Neither approach is strictly better. If you want your dashboard to be reviewable text in version control, Homepage fits that workflow. If you want to click through setup and keep secrets encrypted at rest on the box, Lab Dash's model is the one described here.
Licence, maintenance and upgrade cost
Lab Dash is GPL-3.0. For a homelab deployment that means you can run it, modify it and redistribute it under the same licence, and if you distribute a modified version you have to make the source available under GPL-3.0 terms. Running it privately on your own server does not trigger distribution obligations. This is a summary of the licence identifier, not legal advice; read the full text if you plan to ship a fork. On maintenance, the release cadence visible in the supplied data is uneven: v1.3.7 and v1.3.6 landed three days apart in February 2026, then v1.3.8 arrived in July 2026. The README's contributing guidelines ask for one feature per PR and require that AI-generated code be reviewed and tested before submission, which tells you the maintainer is thinking about review quality. The upgrade cost itself is low and documented: docker compose pull followed by docker compose up -d, or the Portainer re-pull toggle. Because the compose file uses the latest tag by default, your real upgrade cost is the risk of an unpinned image changing under you. Pinning to a tag such as v1.3.8 and bumping deliberately is the cheaper habit if you care about the dashboard staying up.
Editorial conclusion
Adopt Lab Dash if you already run Docker Compose on a single homelab host, want one internally hosted page for shortcuts and service health, and are comfortable reviewing what a privileged container with the Docker socket can do on that host. Do not adopt it if you need multi-host aggregation, or if your threat model treats the dashboard as a lower-trust surface than the services it monitors. Before deploying, read the compose file line by line, decide whether you actually need privileged: true and the /var/run/docker.sock mount, replace the SECRET placeholder with output from openssl rand -base64 32, and confirm the config and uploads volumes point at directories you back up yourself.
Community notes