Container Registry
The project publishes to:
registry.example.com/YOUR-USER/homelab-dashboard:latest
registry.example.com/YOUR-USER/homelab-dashboard:<git-sha>
registry.example.com/YOUR-USER/homelab-dashboard:vX.Y.Z
registry.example.com/YOUR-USER/homelab-dashboard:vX.Y.Z-001-g<short-sha>
Current Iteration Workflow
During active development, changes are usually published as:
git push origin main
docker build \
-t registry.example.com/YOUR-USER/homelab-dashboard:latest \
-t registry.example.com/YOUR-USER/homelab-dashboard:<git-sha> \
.
docker push registry.example.com/YOUR-USER/homelab-dashboard:latest
docker push registry.example.com/YOUR-USER/homelab-dashboard:<git-sha>
docker manifest inspect registry.example.com/YOUR-USER/homelab-dashboard:latest
The commit SHA tag gives a stable rollback target while latest gives the deployment a simple pull target.
Automatic Publishing
.forgejo/workflows/container.yml builds and pushes the image on every push to main when a compatible Forgejo Actions runner is available.
Before a main publish, the workflow checks package.json and fails if the matching
version tag already exists for another commit. Bump the package version before every
release-producing Docker image.
Pushes to main publish:
registry.example.com/YOUR-USER/homelab-dashboard:latest
registry.example.com/YOUR-USER/homelab-dashboard:<git-sha>
registry.example.com/YOUR-USER/homelab-dashboard:v<package.json version>
Successful main publishes also create or update the matching Forgejo Release and
Git tag. Release notes are generated from the matching row in the Release History
table below. Release tag pushes matching v* also publish the semantic version
tag, such as v0.8.1, without moving latest.
Create releases with a normal Forgejo user credential rather than the Actions
GITHUB_TOKEN if you want the release author to show as that user instead of
the automation/Ghost account.
Published images embed the commit SHA in DASHBOARD_BUILD. The running app exposes
version and build from /api/health, /api/admin/session, and /api/dashboard;
the dashboard header shows the package version for quick rollback checks.
This requires a Forgejo Actions runner with a label matching the workflow. If the
run stays in waiting, add or start an Actions runner for the repository/instance.
The Docker login step uses repo Actions secrets named REGISTRY_USERNAME and
REGISTRY_PASSWORD because this Forgejo instance's default GITHUB_TOKEN does
not have package push access.
Forgejo Actions Runner
This homelab uses a repository-scoped runner named homelab-dashboard-docker with
the docker label. Runner registration state and action/build caches live in
Docker named volumes so they survive container restarts:
homelab-forgejo-runner-data
homelab-forgejo-dind-data
The local containers are:
homelab-forgejo-runner
homelab-forgejo-dind
The runner uses data.forgejo.org/forgejo/runner:12. Docker image builds run
against an isolated docker:dind daemon on homelab-forgejo-runner-net, keeping
workflow Docker access separate from the host Docker socket.
Check runner health:
docker ps --filter "name=homelab-forgejo"
docker logs --tail 100 homelab-forgejo-runner
Verify the workflow Docker daemon is reachable:
docker run --rm \
--network homelab-forgejo-runner-net \
-e DOCKER_HOST=tcp://homelab-forgejo-dind:2375 \
docker:cli docker version
If the runner registration is lost, generate a repository runner registration
token from Forgejo and register a replacement runner with the docker label.
Do not commit runner registration files, tokens, or Docker credentials to the
repository.
Semantic Releases
Create semantic releases by bumping the package version before pushing to main:
npm version patch --no-git-tag-version
git commit -am "Bump version to vX.Y.Z"
git push origin main
The main push publishes:
registry.example.com/YOUR-USER/homelab-dashboard:latest
registry.example.com/YOUR-USER/homelab-dashboard:<git-sha>
registry.example.com/YOUR-USER/homelab-dashboard:vX.Y.Z
It also creates the Forgejo Release and Git tag for vX.Y.Z. Use manual git tag
pushes only for exceptional repair work or historical release reconstruction.
Release History
The project originally stayed at package.json version 0.1.0 while the dashboard
grew through several large feature slices. The registry now has clean semantic
milestone tags:
| Tag | Milestone |
|---|---|
v0.1.0 |
Initial React dashboard scaffold before Docker publishing. |
v0.2.0 |
Node backend, Docker, environment config, and integration foundation. |
v0.3.0 |
Admin registration, login, users, and baseline security checks. |
v0.4.0 |
Realtime dashboard, layouts, branding, and core media/network integrations. |
v0.5.0 |
Operations layer with Proxmox, lab view, diagnostics, alerts, and admin recovery. |
v0.6.0 |
Notifications, guarded restore, audit log, password change, and hardening. |
v0.7.0 |
Storage fleet, SQLite persistence, white-label branding, and release tooling. |
v0.8.0 |
Server-side history, diagnostic trends/playbooks, and wallboard/mobile polish. |
v0.8.1 |
Release workflow guardrails for required version bumps and automatic Forgejo Releases. |
v0.8.2 |
Configurable storage, ASUSTOR temperature, and Proxmox resource warning thresholds. |
v0.8.4 |
Persistent Forgejo Actions runner setup, registry credentials, and operator documentation. |
v0.8.5 |
Filtered history exports, admin threshold polish, and compact mobile lab controls. |
v0.8.6 |
Opt-in ASUSTOR temperature alerts and module-menu admin integration configuration. |
v0.8.7 |
Page-based admin console navigation for users, white-labeling, recovery, health, security, and integrations. |
v0.8.8 |
Sidebar admin navigation with clear active-page highlighting. |
v0.8.9 |
Admin sidebar participates in the full page scroll instead of using an independent scroll region. |
v0.8.10 |
Admin diagnostic drill-down cards and clearer Storage Health aggregate/warning presentation. |
v0.8.11 |
UniFi Network top-client cards and named UniFi NAS source panels. |
v0.8.12 |
Simplified UniFi Network and Seerr cards with unified Storage Systems visibility. |
v0.8.13 |
Grouped Storage Health admin setup fields by NAS source. |
v0.8.14 |
Improved Storage Health admin section contrast. |
v0.8.15 |
Cached dashboard snapshots and lazy admin diagnostics for faster page loads. |
v0.8.16 |
Combined Storage Health system capacity and pool/volume summaries. |
v0.8.18 |
Reverted UniFi NAS URL reachability while a working integration path is researched. |
v0.8.19 |
Added UniFi NAS SNMP storage-row fallback diagnostics. |
v0.8.20 |
Added UniFi NAS SNMP UCD disk-table capacity fallback. |
v0.8.21 |
Cleaned TrueNAS alert HTML and added clearer failed-job details. |
v0.8.22 |
Migrated TrueNAS Storage Health polling to JSON-RPC over WebSocket. |
v0.8.23 |
Added TrueNAS JSON-RPC API-key fallback handling and UniFi NAS SNMP table-count diagnostics. |
v0.8.24 |
Scoped TrueNAS Storage Health job warnings to storage-related jobs. |
v0.8.25 |
Added UniFi NAS local Drive API polling with SNMP fallback. |
v0.8.26 |
Fixed UniFi NAS local API backend startup after adding Drive API polling. |
v0.8.27 |
Broadened UniFi NAS Drive API parsing and added local API response-shape diagnostics. |
v0.8.28 |
Added UniFi NAS SNMP positional row fallback for partial one-row tables. |
v0.8.29 |
Added UniFi NAS SNMP sample-value diagnostics when capacity rows cannot be built. |
v0.8.30 |
Ignored UniFi NAS SNMP No Such Object replies and clarified local API requirement. |
v0.8.31 |
Extracted Storage Health overview rendering and indexed storage checks in one pass. |
v0.8.32 |
Extracted backend module definitions and environment mapping from the main server. |
v0.8.33 |
Extracted Proxmox overview rendering and indexed Proxmox checks in one pass. |
v0.8.34 |
Extracted UniFi Network overview rendering and indexed device rows in one pass. |
v0.8.35 |
Extracted dashboard trend rendering and indexed diagnostic samples once per snapshot. |
v0.8.36 |
Extracted the shared backend JSON fetcher from the main server. |
v0.8.37 |
Extracted backend auth/session helpers from the main server. |
v0.8.38 |
Extracted dashboard history helpers from the main server. |
v0.8.39 |
Extracted dashboard alert aggregation helpers from the main server. |
v0.8.40 |
Extracted notification delivery helpers from the main server. |
v0.8.41 |
Extracted audit log helpers from the main server. |
v0.8.42 |
Extracted dashboard diagnostics summary helpers from the main server. |
v0.8.43 |
Extracted Seerr integration helpers from the main server. |
v0.8.44 |
Extracted Uptime Kuma integration helpers from the main server. |
v0.8.45 |
Extracted Proxmox, Plex, media, and Storage Health backend helpers from the main server. |
v0.8.46 |
Extracted UniFi Network backend helpers and discovery handling from the main server. |
v0.8.47 |
Extracted dashboard runtime caching, polling, and realtime payload orchestration from the main server. |
v0.8.48 |
Extracted SQLite persistence, settings, event-log, and legacy JSON migration helpers from the main server. |
v0.8.49 |
Extracted admin action handlers and the authentication screen from the main files. |
v0.8.50 |
Extracted the admin shell/sidebar and polished admin page navigation state. |
v0.8.51 |
Added shared status, check-dot, and empty-state UI primitives across dashboard surfaces. |
v0.8.52 |
Added stable loading skeletons for dashboard and admin health loading states. |
v0.8.53 |
Polished admin form controls, action buttons, and security/user form grouping. |
v0.8.54 |
Tightened dashboard integration card layout, meta rows, and card body scrolling. |
v0.8.55 |
Polished Storage Health unknown-capacity states and capacity row hierarchy. |
v0.8.56 |
Improved diagnostics drawer scanability with prioritized rows and status-toned headers. |
v0.8.57 |
Polished dashboard header controls, compact density, mobile layout, and keyboard focus states. |
v0.8.58 |
Added dashboard action tooltips and pressed states for toggle controls. |
v0.8.59 |
Broadened UniFi NAS local Drive API parsing for newer pool and global disk payloads. |
v0.8.60 |
Made Storage Health admin source/device setup sections collapsible. |
v0.8.61 |
Updated Forgejo releases to use release-specific notes from the registry history. |
v0.8.62 |
Preferred UniFi NAS local login sessions over API-key auth when both are configured. |
v0.8.63 |
Accepted bare host/IP values in UniFi NAS local API URL fields. |
v0.8.64 |
Fell back to UniFi NAS API-key auth when local session login requires MFA. |
v0.8.65 |
Showed alert reasons directly in the dashboard alert rail. |
v0.8.66 |
Avoided repeated UniFi NAS session login attempts after MFA or rate-limit blocks. |
v0.8.67 |
Let UniFi Network use configured site/host IDs when site discovery fails. |
v0.8.68 |
Improved lab-view visual separation and made Proxmox backup task polling compatible with stricter task endpoints. |
v0.8.69 |
Created Forgejo releases with the configured registry user instead of the Actions Ghost user. |
The milestone publisher starts at v0.2.0 because v0.1.0 was a local Vite
scaffold before the project had a Dockerfile and registry workflow.
Preview milestone registry tags without building:
npm run images:milestones
Build and push the clean milestone tags:
npm run images:milestones -- --push
Use npm run images:backfill when every historical Docker-ready commit should be
previewed with sequence tags, and npm run images:backfill -- --push only when
intentionally publishing that full historical set.
Pulling From A Protected Registry
On the deployment host:
docker login registry.example.com
docker compose pull
docker compose up -d
If login succeeds but pull returns unauthorized, check the Forgejo package/repository permissions for the user or token. The Docker client may be authenticated but still lack package read permission.
Deployment
On the dashboard VM:
docker compose pull
docker compose up -d
Then confirm the container is running:
docker compose ps
docker logs homelab-dashboard