Incus Backup UI
Dark-mode control plane for Incus VM backups using ZFS block devices, Restic, and S3-compatible storage.
Layout
management/: Central Express API with cookie login, SQLite storage, node registry, central schedules, and proxy calls to node agents.backend/: Node agent API that runs on each Incus host, validates Incus VMs, runs host commands withspawn, manages in-memory jobs, and enforces one active backup/restore per VM.frontend/: React/Vite dashboard for management login, node management, health, VM status, snapshots, backup jobs, and explicit destructive restore confirmation.incus-backup-ui-plan.md: Product and implementation plan.
Node Agent
cd backend
cp .env.example .env
npm install
npm run dev
The node agent must run on every Incus host with permission to access Incus, ZFS, /dev/zvol, Restic, and S3 credentials. In production this usually means running it as root or through a tightly scoped service account with the needed privileges.
Set API_TOKEN in backend/.env; the management server uses that token when calling the agent.
Required commands:
incuszfszpoolresticudevadmdd
Management API
cd management
cp .env.example .env
npm install
npm run dev
The management API stores nodes, users, sessions, and central schedules in SQLite. Configure the first admin user through AUTH_USERNAME and AUTH_PASSWORD before the first start. If no password is configured, the development fallback is admin.
The management API uses Node's built-in SQLite module and requires Node.js 22.5 or newer.
Reset an existing admin password without deleting the database:
cd management
npm run reset-password -- admin "new-password"
Frontend
cd frontend
npm install
npm run dev
Set VITE_API_URL if the management API is not available at http://localhost:3100/api.
Settings Page
The UI includes a Settings page for editing selected node-agent environment values through the management API. The management server forwards those requests to the selected node agent.
Changing most node-agent values applies to new API calls and jobs immediately. Changing a node-agent PORT requires restarting that agent process.
Safety Notes
Restore is intentionally guarded twice: the backend validates the snapshot against the VM, and the UI requires typing the VM name before sending the restore request. Restore jobs are never retried automatically.
Deployment
See docs/deployment.md for systemd units, management/agent split, and production setup notes.