Dashboard
- Date
- Author
NINikki Sophie 🌸- Stack
- Next.js, TypeScript, Tailwind CSS, shadcn/ui, PostgreSQL, Prisma, Better Auth, Docker
- Tags
- Front-EndBack-EndFull-StackWebsiteSelf-Hosted
Pictures
Overview
A dashboard for one home server that runs on that server. Every Docker container is a tile with its status, usage and live numbers from its app, and each opens a window to run it from: logs and a console, its files in an editor, its git history and a button to redeploy. New services come from templates and get their Caddy site written for them.
Features
Watching the server
- Every service at a glance: CPU, memory, disk, network and processes for the server, then every container in groups, each with a sparkline and what its app knows: downloads in qBittorrent, players on Minecraft, shows in Jellyfin, sites in Caddy, and whether my stream relay is live.
- A record a minute, whether or not anyone has the page open: the server's and each service's usage a week back, and every website's uptime over a day, week and month, with each outage and why.
- Alerts by mail: a service that stopped without anyone stopping it, the disk filling, a website failing three checks in a row, or a certificate close to running out. They show under a bell, and are mailed once they've lasted two minutes and again once they're fixed.
Running it
- A window for each service: start, stop, restart, read and type into its logs, and edit its compose file and
.env, which Compose checks before they're saved. - A code editor and git, built in: the stack's folder as a tree, highlighting for TypeScript, YAML, Dockerfiles and more, Markdown previewed as GitHub shows it, and commits, branches and diffs side by side.
- New services in a minute: about 200 templates, any image on Docker Hub, a pasted
docker runcommand, a compose file or a git repository. Dashboard makes the folder, starts it, writes its Caddy site and reloads Caddy, and undoes all of it if a step fails. - Updates, found and applied: newer images and new commits, checked every few hours, applied one at a time or all at once, with a warning before a new major version. Ubuntu's own packages too, security fixes first.
- Nightly backups with restic: every Postgres database and every service's folder, seven nights kept, and any one of them restored from the dashboard without touching the rest.
- Browsing storage: Garage's buckets as folders of thumbnails, to open, play or delete from.
Arranging it
- A grid you arrange yourself: drag tiles by a tab, resize them by a corner knob in whole columns and rows, and do the same with whole sections. A bigger tile shows more, like a full graph of its CPU.
- One arrangement per screen width, so arranging on a laptop leaves the phone's alone. A width that hasn't been arranged starts from the nearest one that has.
- Keyboard and touch: arrow keys move a tile a cell at a time, and holding a tile on a phone picks it up, so a swipe still scrolls.

People
- Invites with roles: owner, admin, operator and viewer, where operators and viewers only see the groups they're given. A friend can restart the game servers without seeing anything else.
- Passwords, passkeys and two-factor codes, a list of signed-in devices, and an activity log of every start, stop, update, saved file and commit, with who did it and whether it worked.
How it's built
It runs on the server it controls. Dashboard has the Docker socket and the home folder mounted at the same path as on the host, so Compose files find their files where they expect them. Compose and git run in short-lived containers of their official images, so Dashboard's own image needs neither, and things only the host can do, like installing Ubuntu updates, run as systemd jobs that keep going when Docker restarts underneath them.
It updates itself. Pushing to master shows up as an update on Dashboard's own tile. Applying it builds the new version, runs the database migrations in a one-off container and only then swaps the running dashboard, and a failed migration leaves the old one running.
Access is checked on every door. Each route and server action checks the person's role on the server, and a test reads the source and fails if a new one forgets to.
Registries asked politely. Update checks only send HEAD requests for manifests, which Docker Hub doesn't count against its pull limit.
Stack
Next.js (App Router, server actions), React, TypeScript, Better Auth, Prisma on PostgreSQL, the Docker Engine API, restic, Garage, Nodemailer, dnd kit, Tailwind CSS and shadcn/ui, Bun.


