README.md

June 13, 2026 · View on GitHub

backupctl
Backup orchestration for databases, files, or both. One config, zero babysitting.

NestJS 11 TypeScript Docker PostgreSQL Restic Jest


backupctl demo

backupctl is a standalone Docker service that orchestrates scheduled backups for multiple projects — databases (PostgreSQL, MySQL, MongoDB), files, or both — with encrypted remote storage via restic, configurable notifications, and a full CLI for day-to-day operations.

Highlights

  • Multi-project — single service manages dozens of projects from one YAML config
  • Flexible scope — back up databases, files, or both per project; PostgreSQL, MySQL, MongoDB out of the box
  • Restic + Hetzner Storage Box — encrypted, deduplicated backups over SFTP
  • GPG encryption — optional per-project dump encryption before upload
  • Notifications — Slack, Email (SMTP/TLS), Webhook (JSON + markdown)
  • Uptime Kuma monitoring — optional heartbeat push monitors for passive failure detection
  • Pre/post hooks — run arbitrary shell commands around each backup
  • Retry with backoff — configurable exponential retry for transient failures
  • Audit trail — every run tracked in PostgreSQL with real-time stage progress
  • Crash recovery — orphan detection, lock cleanup, fallback replay on startup
  • 15 CLI commands — backup, restore, status, health, snapshots, prune, logs, config, cache, restic passthrough, upgrade
  • Dry run — validates config, adapters, connectivity, disk, and GPG before a real run
  • Zero-edit install — interactive wizard generates .env, SSH keys, and project config

Quick Start

# One-line install (pulls pre-built image)
curl -fsSL https://raw.githubusercontent.com/vineethkrishnan/backupctl/main/scripts/get-backupctl.sh | bash

# Or from source
git clone https://github.com/vineethkrishnan/backupctl.git && cd backupctl
./scripts/install.sh

# Verify
docker exec backupctl node dist/cli.js health

# Run first backup
docker exec backupctl node dist/cli.js run myproject --dry-run
docker exec backupctl node dist/cli.js run myproject
# Docker Hub
docker pull vineethnkrishnan/backupctl:latest

# GitHub Container Registry
docker pull ghcr.io/vineethkrishnan/backupctl:latest

CLI at a Glance

backupctl run <project> [--dry-run]    # trigger or simulate backup
backupctl run --all                    # back up all projects
backupctl status [project]             # backup status
backupctl health                       # audit DB, restic, disk, SSH
backupctl restore <proj> <snap> <path> # restore from snapshot
backupctl snapshots <project>          # list restic snapshots
backupctl prune <project> | --all      # remove old snapshots
backupctl logs <project> [--failed]    # query audit log
backupctl config validate|show|reload  # config management
backupctl cache <project> [--clear]    # restic cache management
backupctl restic <project> <cmd>       # restic passthrough
backupctl upgrade                     # check for updates

Inside Docker: docker exec backupctl node dist/cli.js <command>

Architecture

Hexagonal (Ports & Adapters) with strict layer separation.

                  ┌──────────────────────────────────────┐
                  │          Infrastructure               │
                  │   CLI · HTTP · Scheduler  (driving)   │
                  │              │                        │
                  │   ┌──────────┴───────────┐           │
                  │   │   Application Layer   │           │
                  │   │ Orchestrator·Registry │           │
                  │   └──────────┬───────────┘           │
                  │              │                        │
                  │   ┌──────────┴───────────┐           │
                  │   │    Domain Layer       │           │
                  │   │ Ports·Models·Policies │           │
                  │   └──────────┬───────────┘           │
                  │              │                        │
                  │   Adapters (driven)                   │
                  │   Dumpers·Restic·Notifiers·GPG·Audit  │
                  └──────────────────────────────────────┘

infrastructure/application/domain/ — never the reverse.

Documentation

backupctl.vinelab.in — full documentation site.

Also available in docs/:

#DocumentWhat's inside
1IntroductionFeatures, design goals, tech stack
2ArchitectureHexagonal design, layers, naming, project structure
3RequirementsPRD summary, goals, non-goals, audit schema
4InstallationPrerequisites, wizard, manual setup, Docker
5Configuration.env reference, projects.yml schema, resolution rules
6CLI ReferenceAll 15 commands with syntax, options, exit codes, examples
7Bash Scriptsinstall.sh, dev.sh, backupctl-manage.sh
8Backup Flow11-step flow, retry, concurrency, recovery, notifications
9Restore GuidePer-DB restore, decrypt, decompress, --guide
10CheatsheetDaily ops quick reference, one-liners
11Adding AdaptersExtending with new DB engines, notifiers, storage backends
12TroubleshootingCommon issues, debug commands, log locations
16MonitoringUptime Kuma push monitors, setup, heartbeat details

Tech Stack

ComponentTechnology
RuntimeNode.js 20 LTS
FrameworkNestJS 11
CLInest-commander
ORMTypeORM (explicit migrations)
Audit DBPostgreSQL 16
Scheduler@nestjs/schedule
LoggingWinston + daily rotation
ContainersDocker + Docker Compose
Remote storageRestic → Hetzner Storage Box (SFTP)
EncryptionGPG
TestingJest (342 tests)

Contributing

npm install          # install deps
npm run start:dev    # dev server (watch)
npm test             # run tests
npm run lint         # lint
npm run build        # production build

See Adding Adapters for extending the system.

License

MIT