neuron-explorer
Qwen3.5‑4B 전용 조향형 뉴런 탐색기, 모든 MLP 뉴런을 밀어 결과를 보관·탐색
A self-hosted mobile-first homelab dashboard PWA for manual services, health checks, and future control-plane integrations.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗Self-hosted homelab control plane — save your services, check health on demand, open everything from your phone.
Website and documentation: uniskela.github.io/UniHomelabDash
Brand assets and palette: docs/branding/BRAND.md
Security: Authentication is required for dashboard access. On first run, create the admin account at
/setup. SetSESSION_SECRETin production. Do not expose to the public internet without HTTPS and access control. See SECURITY.md.
Create a .env file with a strong SESSION_SECRET (see .env.example), then start the stack:
echo "SESSION_SECRET=$(openssl rand -base64 32)" >> .env
docker compose up --build
Open http://localhost:3000. On first visit you will be prompted to create an admin account at /setup.
The Compose file mounts a named volume at /app/data for SQLite persistence. It intentionally does not mount /var/run/docker.sock.
If port 3000 is already in use:
HOST_PORT=3003 docker compose up --build
docker compose up --build -d.docker compose up --build -d.docker compose up --build -d.UniHomelabDash is pre-1.0. Releases may progress through v0.10.0, v0.25.0, and beyond; v1.0.0 is an explicit stability milestone rather than an automatic numbering threshold.
docker compose up --build -d.docker compose up --build -d.docker compose up --build -d.providers table on startup.docker-compose.override.yml, then enable the integration in Settings → Integrations./var/run/docker.sock.SESSION_SECRET to your .env (see .env.example).docker compose up --build -d./setup to create the admin account (existing services data in the SQLite volume is preserved).COOKIE_SECURE=true and PUBLIC_URL to your public origin (see .env.example).Copy .env.example for environment variables. SESSION_SECRET is required in production containers. Optional settings include DATABASE_PATH, HOST_PORT, COOKIE_SECURE, PUBLIC_URL, TRUST_PROXY_HEADERS, ALLOWED_HOSTS, and ALLOWED_DEV_ORIGIN.
Production image installs require SESSION_SECRET. Generate one before docker run or add it to a .env file for Compose (see Quick start).
Public source code and releases: github.com/uniskela/UniHomelabDash.
CI builds OCI images on every push to main and on version tags (v0.1.0, etc.) via .github/workflows/docker-image.yml (GHCR and Docker Hub) and .github/workflows/ci.yml (app CI).
| Registry | Image | Notes |
|---|---|---|
| GHCR | ghcr.io/uniskela/unihomelabdash | Built by GitHub Actions |
| Docker Hub | uniskela/unihomelabdash | hub.docker.com/r/uniskela/unihomelabdash — same tags as GHCR |
Either registry works for installs. Use whichever is easier on your network.
The same tags are published to GHCR and Docker Hub:
| Tag | When published | GHCR | Docker Hub |
|---|---|---|---|
latest | Every push to main; also updated on release tags | ghcr.io/uniskela/unihomelabdash:latest | uniskela/unihomelabdash:latest |
vX.Y.Z | Git tag vX.Y.Z | ghcr.io/uniskela/unihomelabdash:v0.1.0 | uniskela/unihomelabdash:v0.1.0 |
X.Y.Z | Same release (semver without v prefix) | ghcr.io/uniskela/unihomelabdash:0.1.0 | uniskela/unihomelabdash:0.1.0 |
Pin a release with either v0.1.0 or 0.1.0 — both point at the same image.
GHCR:
docker pull ghcr.io/uniskela/unihomelabdash:latest
docker run -d --name unihomelabdash \
-p 3000:3000 \
-e SESSION_SECRET="$(openssl rand -base64 32)" \
-v unihomelabdash-data:/app/data \
--restart unless-stopped \
ghcr.io/uniskela/unihomelabdash:latest
For a fixed secret across restarts, use --env-file .env instead of -e SESSION_SECRET=... (see .env.example).
Docker Hub:
docker pull uniskela/unihomelabdash:latest
docker run -d --name unihomelabdash \
-p 3000:3000 \
-e SESSION_SECRET="$(openssl rand -base64 32)" \
-v unihomelabdash-data:/app/data \
--restart unless-stopped \
uniskela/unihomelabdash:latest
Use image instead of build (for example in docker-compose.override.yml). Create a .env file with SESSION_SECRET first (see Quick start):
services:
unihomelabdash:
image: ghcr.io/uniskela/unihomelabdash:latest
# image: uniskela/unihomelabdash:latest # Docker Hub
container_name: unihomelabdash
ports:
- "${HOST_PORT:-3000}:3000"
environment:
DATABASE_PATH: /app/data/unihomelabdash.sqlite
SESSION_SECRET: ${SESSION_SECRET:?Set SESSION_SECRET in a .env file or shell environment}
COOKIE_SECURE: ${COOKIE_SECURE:-false}
PUBLIC_URL: ${PUBLIC_URL:-}
TRUST_PROXY_HEADERS: ${TRUST_PROXY_HEADERS:-false}
ALLOWED_HOSTS: ${ALLOWED_HOSTS:-}
volumes:
- unihomelabdash-data:/app/data
restart: unless-stopped
volumes:
unihomelabdash-data:
| Secret | Required | Purpose |
|---|---|---|
REGISTRY_USERNAME | Optional | GitHub username for GHCR (defaults to the workflow actor) |
REGISTRY_TOKEN | Optional | GitHub PAT with write:packages (defaults to the automatic workflow token) |
DOCKERHUB_USERNAME | For Docker Hub push | Docker Hub namespace (uniskela) |
DOCKERHUB_TOKEN | For Docker Hub push | Docker Hub access token |
RELEASE_PLEASE_TOKEN | Optional | PAT for Release Please so created tags/releases can trigger other workflows (falls back to GITHUB_TOKEN) |
Secret names must be alphanumeric or underscore only, and cannot start with GITHUB_. Use REGISTRY_TOKEN for a custom GHCR PAT — not GITHUB_TOKEN.
For the first GHCR push, set Settings → Actions → General → Workflow permissions → Read and write permissions.
Releases are managed with Release Please
(.github/workflows/release-please.yml, release-please-config.json,
.release-please-manifest.json). Prefer Conventional Commits (feat:, fix:,
docs:, …) so changelog sections stay accurate.
Tag v0.9.1 and the GitHub Release are published. Images: v0.9.1 / 0.9.1 / latest on GHCR and Docker Hub.
If a future Release Please tag does not trigger image builds (Actions token chaining), manually start Build Docker Image (workflow_dispatch) and select the release tag as the ref. Set repository secret RELEASE_PLEASE_TOKEN (PAT with contents + pull-requests) before future releases so tag creation can trigger image builds automatically.
Release title:
UniHomelabDash v0.9.1
Suggested release highlights (Release Please will also generate commit-based notes):
## Highlights
- Consistent status colours across dashboard, services, and containers.
- Calmer Containers page: manual Refresh, filters first, Display options on demand.
- Settings grouped into Integrations / Account / App & checks / Advanced.
- Larger touch targets, reduced-motion support, and accessibility fixes.
## Upgrade notes
- Rebuild/restart as usual (`docker compose up --build -d`). No schema migration or new environment variable is required.
- Provider permissions and actions are unchanged from v0.9.0.
## Container images
- `docker pull ghcr.io/uniskela/unihomelabdash:v0.9.1`
- `docker pull ghcr.io/uniskela/unihomelabdash:0.9.1`
- `docker pull uniskela/unihomelabdash:v0.9.1`
- `docker pull uniskela/unihomelabdash:0.9.1`
After each meaningful feat / fix land on main, Release Please opens or updates a release PR. Merge that PR to tag and publish. Optional secret RELEASE_PLEASE_TOKEN lets the created tag trigger image builds under a non-GITHUB_TOKEN identity.
If a PR uses a Release-As: X.Y.Z footer to force the next version, preserve that footer in the squash commit message when merging to main (squash defaults often keep only the title).
v0.9.0 was tagged manually before Release Please:
git switch main
git pull
git tag -a v0.9.0 -m "v0.9.0"
git push origin v0.9.0
Publish a GitHub Release from tag v0.9.0 if recreating notes.
The project maintainer may also build images to a private self-hosted Gitea registry on an internal network (LAN/Tailscale only). This is not a public distribution channel — contributors and users should use GitHub, GHCR, or Docker Hub only.
git.pike.homes/alex/unihomelabdash (reachable only on maintainer network)REGISTRY_USERNAME, REGISTRY_TOKEN (Gitea package write)Do not document or share internal hostnames in issues, PRs, or release notes intended for the public.
| Dashboard | Services |
|---|---|
| Add service form |
|---|
Demo data only (example.local URLs). Regenerate after UI or branding changes:
npm run icons:export # when brand SVG assets change
npm run build
npm run screenshots
When adding or editing a service, set an optional health check URL. Use the service root or a dedicated endpoint (for example /health). Tap Check on a card or Check all on the dashboard.
Behaviour in v0.1.0:
Edit and delete services from the Services page (overflow menu on each card). The dashboard is for quick open and health overview: degraded services appear once under Needs attention, and everything else under Other services.
npm install
npm run dev
Open http://localhost:3000.
Manual services are stored in SQLite at data/unihomelabdash.sqlite by default. Set DATABASE_PATH to use a different location.
The GitHub Pages site is an isolated Astro/Starlight project under site/:
npm install --prefix site
npm run site:dev
Before submitting website or documentation changes:
npm run site:test
npm run site:check
npm run site:build
The production build targets the GitHub Pages project path at /UniHomelabDash/.
npm run dev:lan
Then open http://<your-host-ip>:3004 (find your IP with hostname -I or ip a).
Next.js blocks cross-origin dev assets by default. This project configures allowedDevOrigins in next.config.ts for common private LAN ranges. If you still see webpack-hmr WebSocket errors:
ALLOWED_DEV_ORIGIN=192.168.0.7 npm run dev:lan
See the Next.js allowedDevOrigins docs.
For production-like testing without HMR:
npm run build && npm run start:lan
npm run dev # local development (port 3000)
npm run dev:lan # dev server on 0.0.0.0:3004 for LAN testing
npm run lint
npm run typecheck
npm run build
npm run start:lan # production server on 0.0.0.0:3004
npm run db:generate
npm run db:migrate
npm run reset-admin # recover admin access (see below)
npm run test
npm run screenshots # capture docs/screenshots (requires build)
npm run site:dev # local documentation site
npm run site:test
npm run site:check
npm run site:build
If you forget the admin password, reset it against the SQLite database.
Docker Compose (non-interactive password via env):
RESET_ADMIN_PASSWORD='your-new-password' \
docker compose exec unihomelabdash \
node scripts/reset-admin.mjs --username admin --confirm
Local development:
npm run reset-admin -- --username admin --confirm
The script updates the single admin user (or creates one if missing) and marks setup complete. It requires --confirm and never prints the password.
Change your password from Settings while signed in.
Authentication is required before dashboard access. Privileged integrations are not enabled yet.
SESSION_SECRET in production — see SECURITY.mdContributions are welcome. Start with CONTRIBUTING.md for setup, PR expectations, and scope rules.
MIT — see LICENSE.