A small web-based admin dashboard for Pubky homeservers. Built with Next.js (App Router), React, and Tailwind + shadcn/ui.
The UI lives under a single route: /dashboard (the home page redirects there).
The dashboard has 5 tabs:
- Overview: Shows homeserver stats from
GET /infoincluding connection status, public key, addresses, version, and user/storage statistics - Users: Disable / enable a user by pubkey via
POST /users/{pubkey}/disableandPOST /users/{pubkey}/enable. The disabled-users list is fetched live from the/users/disabledadmin endpoint. - Invites: Generate signup tokens via
GET /generate_signup_tokenwith QR code display for easy mobile app signup; view invite statistics (total generated, used, unused) - Files: Full WebDAV file browser (list/read/write/delete/move/create directories) using the
/dav/*endpoint (Basic Auth). Includes admin "Delete from path" for removing entries by path - API: API Explorer for admin/client/metrics endpoints (manual requests)
A real-time Logs tab will be added once the homeserver exposes a logs admin endpoint; see
docs/AUDIT-2026-05-19.mdfor the v1.0 punch list.
The navbar Settings (gear) button opens Settings with two tabs: Config (read-only view of the real config.toml with sensitive fields redacted) and Cloudflare (configure Cloudflare Tunnel token and domain for public access without port forwarding).
- Node.js 20.9+ and npm (Next.js 16.0.10 requires Node 20.9+)
- A running Pubky homeserver - every UI section above is wired to live admin endpoints
npm installCopy .env.example to .env.local (or create .env.local manually):
cp .env.example .env.localEdit .env.local with your homeserver details:
# Homeserver admin endpoint (server-only variables)
ADMIN_BASE_URL=http://localhost:6288
ADMIN_TOKEN=your-admin-passwordNote: These are server-only environment variables (not prefixed with NEXT_PUBLIC_*) to keep sensitive credentials secure. They are only accessible in API routes and server-side code, never exposed to the client browser.
npm run devOpen http://localhost:8080 in your browser.
npm run build
npm startThe dashboard can be deployed using Docker, either standalone or as part of an Umbrel app.
Build the Docker image:
docker build -t homeserver-dashboard .Run the container:
docker run -d \
-p 8080:8080 \
-e PORT=8080 \
-e ADMIN_BASE_URL=http://homeserver:6288 \
-e ADMIN_TOKEN=your-admin-password \
homeserver-dashboardThe dashboard is included in the pubky-homeserver Umbrel app. When deployed via Umbrel:
- The dashboard runs as the
webservice indocker-compose.yml - Environment variables (
ADMIN_BASE_URL,ADMIN_TOKEN) are automatically configured - The dashboard connects to the homeserver service via Docker networking (
http://homeserver:6288) - Access is provided through Umbrel's app proxy (no direct port exposure needed)
The Dockerfile uses Next.js standalone output for optimal image size and includes:
- Multi-stage build for smaller production image
- Non-root user for security
- Proper handling of server-only environment variables
| Variable | Description | Required | Default | Notes |
|---|---|---|---|---|
ADMIN_BASE_URL |
Homeserver admin API base URL | Yes* | - | Server-only (not exposed to client) |
ADMIN_TOKEN |
Admin password/token | Yes* | - | Server-only (not exposed to client) |
HOMESERVER_CONFIG_PATH |
Path to homeserver config.toml |
No | /app/homeserver-data/config.toml |
For non-Docker setups |
* Required to use the real homeserver APIs
Security Note: These variables are server-only (not prefixed with NEXT_PUBLIC_*) to prevent exposing sensitive credentials to the browser. They are automatically loaded from .env.local in development and from environment variables in production/Docker.
Docker Note: In Docker/Umbrel deployments, use the homeserver service name for ADMIN_BASE_URL (e.g., http://homeserver:6288) instead of localhost to connect via Docker networking.
- Next.js 16 - React framework with App Router
- React 19 - UI library
- TypeScript - Type safety
- Tailwind CSS 4 - Styling
- Shadcn UI - Component library
- Lucide React - Icon library
- Vitest - Unit + integration test runner
- ESLint / Prettier / Knip - Repo hygiene tooling
npm run dev- Start development servernpm run build- Build for productionnpm start- Start production servernpm run lint- Run ESLint (eslint .)npm run lint:fix- Fix lint issues (eslint . --fix)npm run format- Format files with Prettiernpm run format:check- Check formatting (CI-friendly)npm run knip- Check for unused files/deps/exports (seeknip.json)npm test- Run Vitest
This project is maintained by the Pubky team at Synonym. Contributions are welcome via pull request. Please ensure:
- Code follows the existing patterns
- Components use Shadcn UI primitives
- TypeScript types are properly defined
- Error handling is comprehensive
- CI gates (
lint,typecheck,format:check,knip,test:coverage,build,docker) pass before requesting review
- pubky-core - The homeserver this dashboard manages
- franky - Reference UI implementation (design system source)