Backup orchestration control plane with a web dashboard for server onboarding, backup visibility, restore operations, and connectivity verification.
- Fastify API for managing backup servers and schedules
- Web UI at
/dashboardfor day-to-day operations - Encrypted secret storage for SSH and cloud credentials
- Restore snapshot browsing + restore trigger flow
- Server connectivity test endpoint and UI action
- Node.js + TypeScript
- Fastify
- Prisma + PostgreSQL
- SSH transport via
ssh2
- Node.js 20+
- npm
- Docker (for local PostgreSQL)
Copy env template:
cp .env.example .envRequired environment variables:
DATABASE_URL(PostgreSQL connection)ORCHESTRATOR_ENCRYPTION_KEY(base64-encoded 32-byte key)ORCHESTRATOR_ENCRYPTION_KEY_VERSION(e.g.,v1)
Generate a key (example):
openssl rand -base64 32Start PostgreSQL:
docker run -d --name btool-postgres \
-e POSTGRES_USER=postgres \
-e POSTGRES_PASSWORD=postgres \
-e POSTGRES_DB=btool \
-p 5432:5432 postgres:16Install dependencies:
npm installGenerate Prisma client:
npm run prisma:generateRun API + dashboard:
npm run devDefault server address: http://localhost:3000
GET /healthGET /dashboard
Server management:
POST /serversPOST /servers/:serverId/cloud-credentialsPUT /servers/:serverId/source-directoriesPUT /servers/:serverId/schedulePUT /servers/:serverId/retention-policyGET /servers/statusPOST /servers/:serverId/connectivity-test
Backup/restore observability:
GET /servers/:serverId/backups/historyGET /servers/:serverId/backups/history/:attemptId/logGET /servers/:serverId/restores/snapshotsPOST /servers/:serverId/restoresGET /servers/:serverId/restores/historyGET /servers/:serverId/restores/history/:attemptId/logGET /servers/:serverId/retention/prune-logs
Run all tests:
npm testRun a focused test file:
npm run test -- src/modules/dashboard/dashboard.route.spec.ts- Secrets are encrypted before persistence.
- Keep
.envout of source control. - Rotate encryption key versions using
ORCHESTRATOR_ENCRYPTION_KEY_VERSION. - Use the connectivity test in the dashboard to validate SSH configuration before scheduling backups.
The root .gitignore is configured to exclude sensitive files and common local artifacts, including:
.envand.env.*(except.env.example)- private keys/certs (
*.pem,*.key, etc.) - local DB and dump files (
*.db,*.sqlite,*.sql,*.dump) - logs/build outputs (
dist/,*.log, etc.)