No description
  • JavaScript 94.9%
  • Shell 4.5%
  • CSS 0.4%
  • HTML 0.2%
Find a file
Philipp 568c90f06d changed to incubator
added new install script
updated security
updated ETA
2026-06-04 17:19:46 +02:00
agent changed to incubator 2026-06-04 17:19:46 +02:00
deploy changed to incubator 2026-06-04 17:19:46 +02:00
docs changed to incubator 2026-06-04 17:19:46 +02:00
frontend changed to incubator 2026-06-04 17:19:46 +02:00
management changed poll and some UI bugs. 2026-06-04 14:31:53 +02:00
.gitignore added install script for agent 2026-06-04 14:05:50 +02:00
incus-backup-ui-plan.md added install script for agent 2026-06-04 14:05:50 +02:00
README.md changed to incubator 2026-06-04 17:19:46 +02:00

Incus Backup UI

Dark-mode control plane for Incus VM backups using ZFS block devices, Restic, and S3-compatible storage.

Backups include the instance disk or dataset plus Incus metadata captured with incus config show, incus config show --expanded, incus info, and snapshot listing. VM disks are stored as .raw; containers are stored as ZFS send streams (.zfs).

Layout

  • management/: Central Express API with cookie login, SQLite storage, node registry, central schedules, and proxy calls to node agents.
  • agent/: Node agent API that runs on each Incus host, validates Incus VMs, runs host commands with spawn, persists recent 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

curl -fsSL https://forgejo.digital-droplets.de/philschlo/incus-backup-ui/raw/branch/main/deploy/install-agent.sh | sudo sh

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 agent/.env; the management server uses that token when calling the agent. The token is required and must be at least 32 characters long.

The agent persists recent jobs in SQLite through AGENT_DATABASE_PATH (default: ./agent.sqlite). If the agent restarts while a job is queued or running, that job is marked failed on startup so management can poll a final state and stale VM locks are not kept.

The installer clones only the agent-related repository paths and installs incubator for updates and diagnostics:

sudo incubator update
sudo incubator status
sudo incubator logs
sudo incubator doctor

The agent can serve HTTPS directly for private networks:

HTTPS_ENABLED=true
TLS_CERT_FILE="/etc/incus-backup-agent/tls.crt"
TLS_KEY_FILE="/etc/incus-backup-agent/tls.key"

Required commands:

  • incus
  • zfs
  • zpool
  • restic
  • udevadm
  • dd

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. Startup fails if the initial password is missing.

Agent URLs must use https:// by default. For local development only, set ALLOW_INSECURE_AGENT_HTTP=true in management/.env to permit http:// node URLs.

For internal/self-signed agent certificates, set AGENT_CA_FILE in management/.env to the CA certificate that signed the agent certificates.

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 agent validates the snapshot against the VM, and the UI requires typing the VM name before sending the restore request. VM restores write the Restic dump to a staged ZFS volume first, then swap it into place with zfs rename; the previous volume is kept as a pre-restore rollback copy. Restore jobs are never retried automatically.

Deployment

See docs/deployment.md for systemd units, management/agent split, and production setup notes.