Back up Docker containers and host filesystems — encrypted, incremental, and agent-ready.
Quick start · Filesystem backup · Agent integration · CLI reference · Docs
uv tool install --force git+https://github.com/CruxExperts/best-backup.gituv handles the isolated tool environment automatically. This one command works for first install and redeploy/update from GitHub. See Installation if you need to install uv first, or for advanced system-wide /usr/local/bin deployment.
Run bbackup backup and you get an interactive container picker, a live BTOP-style dashboard while the backup runs, and a finished artifact that can be verified, encrypted, and shipped to Google Drive, SFTP, or a local path. Point it at /srv/data and it backs that up too, with gitignore-style excludes. The companion bbman command handles setup, health checks, dependency installs, and self-updates so day-to-day maintenance stays out of the way.
Every command speaks structured JSON, making it compatible with AI agents out of the box: set two env vars, run bbackup skills, and drive the entire tool with --input-json.
Tip
Use --dry-run --output json before destructive restore work or scheduled backup changes. The JSON plan is designed for both humans and automation.
flowchart LR
docker[Docker containers<br/>volumes • configs • networks]
fs[Host filesystems<br/>paths • excludes]
manifest[backup_manifest.json<br/>sizes • SHA-256 • item results]
encrypt[Encryption<br/>AES-256-GCM or RSA-4096]
upload[Remote upload<br/>local • SFTP • rclone]
restore[Restore preflight<br/>manifest verification]
docker --> manifest
fs --> manifest
manifest --> encrypt
encrypt --> upload
manifest --> restore
| Feature | Description | |
|---|---|---|
| 🖥️ | Rich TUI | BTOP-style live dashboard with real-time transfer metrics |
| 🐳 | Docker backup | Containers, volumes, networks, and configs in one shot |
| 📁 | Filesystem backup | Back up any host path recursively with gitignore-style excludes |
| ⚡ | Incremental backups | rsync --link-dest so unchanged data is hardlinked, not copied |
| 🔐 | Encryption | AES-256-GCM (symmetric) or RSA-4096 (asymmetric) at rest |
| ☁️ | Remote storage | Google Drive via rclone, SFTP, or local directory |
| ♻️ | Rotation | Time-based daily/weekly/monthly retention with quota enforcement |
| 📦 | Solid archive | Optional single tarball (and optional whole-file encryption) for upload so remotes get one file instead of many |
| ↩️ | Full restore | Containers, volumes, networks, and filesystem paths; restore from directory or solid archive file |
| 📦 | Backup sets | Named groups of containers defined in config for repeatable runs |
| 🤖 | Agent-friendly CLI | JSON I/O, --input-json, --dry-run, and skill discovery on every command |
| 🛠️ | Management CLI | bbman for setup, health, updates, cleanup, and diagnostics |
- Python 3.12+
- Docker (with socket access for your user)
rsync(system package — used for volume and filesystem backups)rclone(optional, for Google Drive)
uv handles the tool environment automatically.
Run this when uv is already installed:
uv tool install --force git+https://github.com/CruxExperts/best-backup.gitIt creates an isolated uv tool environment and links bbackup and bbman into the uv tool bin directory. The --force flag makes the same command safe for first install, repair, and redeploy/update.
If uv is not installed yet:
curl -LsSf https://astral.sh/uv/install.sh | sh
~/.local/bin/uv tool update-shell
~/.local/bin/uv tool install --force git+https://github.com/CruxExperts/best-backup.gitOpen a new shell after uv tool update-shell so bbackup and bbman are on your PATH.
Most installs should use the uv tool command above. If /usr/local/bin/bbackup
and /usr/local/bin/bbman must be shared by every user or a root-owned
scheduler, see INSTALL.md.
For development setup, local source installs, and uninstall instructions, see INSTALL.md.
# First-time setup: checks Docker, installs deps, creates config
bbman setup
# Interactive backup with live TUI
bbackup backup
# Target specific containers
bbackup backup --containers myapp mydb
# Back up a host filesystem path
bbackup backup --paths /srv/data
# Non-interactive mode (cron or agent)
BBACKUP_OUTPUT=json BBACKUP_NO_INTERACTIVE=1 bbackup backup --backup-set productionSee QUICKSTART.md for a full walk-through: config, remote storage, encryption setup, and more.
Each non-cancelled backup writes backup_manifest.json with the requested scope, filesystem source paths, volume artifact names, item results, errors, file sizes, and SHA-256 hashes. Restore verifies the manifest when present and fails before mutation if files are missing, changed, unlisted, or outside the backup root.
Local, SFTP, and rclone uploads write to .partial destinations first and promote to the final backup name only after the copy succeeds. When encryption succeeds, plaintext staging is removed so local backup artifacts match the encrypted output.
bbackup checks these locations in order:
~/.config/bbackup/config.yaml~/.bbackup/config.yaml/etc/bbackup/config.yaml./config.yaml
A fully annotated template is in config.yaml.example. The minimal setup:
backup:
local_staging: /tmp/bbackup_staging
backup_sets:
production:
containers: [myapp, mydb, nginx]
scope:
volumes: true
configs: true
remotes:
local:
enabled: true
type: local
path: ~/backups/dockerFor rclone remotes you can optionally set rclone_options.transfers and rclone_options.checkers (or top-level rclone.default_options) to tune upload concurrency; both accept 1–32, default 8. See config.yaml.example and docs/architecture.md.
Add a filesystem: section to back up arbitrary host paths:
filesystem:
home-data:
description: "Important home directory data"
targets:
- name: documents
path: /home/user/Documents
enabled: true
excludes:
- "*.tmp"
- ".cache/"
- "node_modules/"Run a named filesystem set:
bbackup backup --filesystem-set home-dataOr pass paths directly, no config needed:
bbackup backup --paths /home/user/docs /srv/data --exclude "*.tmp"bbackup commands
# Docker backup
bbackup backup # Interactive backup with TUI
bbackup backup --backup-set production # Named backup set from config
bbackup backup --containers app db # Specific containers
bbackup backup --incremental # rsync --link-dest mode
bbackup backup --config-only # Skip volumes
bbackup backup --volumes-only # Skip configs
bbackup backup --no-networks # Skip network configs
bbackup backup --remote gdrive # Upload to specific remote
# Filesystem backup
bbackup backup --paths /home/user/docs /srv/data # Back up specific paths
bbackup backup --paths /home/user/docs --exclude "*.tmp"
bbackup backup --filesystem-set home-data # Named set from config
# Restore
bbackup restore --backup-path /path/to/backup --all
bbackup restore --backup-path /path --containers app --rename app:app_v2
bbackup restore --backup-path /path --filesystem documents \
--filesystem-destination /home/user/docs
# Inspect
bbackup list-containers
bbackup list-backup-sets
bbackup list-filesystem-sets
bbackup list-backups
bbackup list-remote-backups --remote gdrive
# Setup
bbackup init-config
bbackup init-encryption --method asymmetric --algorithm rsa-4096
# Agent / non-interactive (available on every command)
bbackup list-containers --output json
bbackup backup --containers app --input-json '{"incremental":true}'
bbackup backup --containers app --dry-run --output json
bbackup skills # discover all capabilities
bbackup skills docker-backup # step-by-step guide + JSON schemasbbman commands
bbman setup # First-time setup wizard
bbman setup --no-interactive # Skip wizard (agent mode)
bbman health # Docker, tools, config health check
bbman health --output json
bbman check-deps # Check dependencies
bbman check-deps --install # Install missing packages
bbman validate-config # Parse and validate config
bbman status # Backup history and totals
bbman status --output json
bbman cleanup # Clean staging dirs and old logs
bbman cleanup --yes # Skip confirmation (agent mode)
bbman diagnostics # Generate diagnostic report
bbman diagnostics --report-file /tmp/report.txt # Save to file
bbman check-updates # Check for newer version
bbman update # Self-update from repo
bbman update --yes # Skip confirmation (agent mode)
bbman repo-url --url URL # Set the update source URL
bbman run backup --containers app # Run bbackup through the wrapper
bbman skills # Discover bbman capabilities
bbman skills maintenance # Step-by-step maintenance guidebbackup and bbman are natively compatible with AI agents. Every command supports structured JSON I/O, progressive skill discovery, and non-interactive execution without extra configuration.
Set these once and every subprocess inherits them:
export BBACKUP_OUTPUT=json # all commands emit a JSON envelope
export BBACKUP_NO_INTERACTIVE=1 # no TUI, no prompts, no pagers| Variable | Effect |
|---|---|
BBACKUP_OUTPUT=json |
All commands emit JSON envelope without --output json |
BBACKUP_NO_INTERACTIVE=1 |
Suppresses TUI, prompts, and pagers system-wide |
bbackup skills # level-0: all skill IDs + summaries (JSON)
bbackup skills docker-backup # level-1: steps, schemas, examples (JSON)
bbackup skills --format markdown # full Markdown skills catalog
bbman skills # level-0 skills for bbman (JSON)
bbman skills maintenance # maintenance skill (JSON)
bbman skills --format markdown # full Markdown skills catalogLevel-0 JSON output:
{
"cli": "bbackup",
"version": "1.8.2",
"agent_hint": "Set BBACKUP_OUTPUT=json and BBACKUP_NO_INTERACTIVE=1 for fully non-interactive use.",
"skills": [
{"id": "docker-backup", "summary": "Back up Docker containers, volumes, networks, and configs.", "common": true},
{"id": "filesystem-backup", "summary": "Back up arbitrary host filesystem paths with gitignore-style excludes.", "common": true},
{"id": "restore", "summary": "Restore containers, volumes, networks, or filesystem paths from a backup.", "common": true}
]
}Every command in JSON mode emits exactly this to stdout. All progress and diagnostic text goes to stderr.
{
"schema_version": "1",
"command": "backup",
"success": true,
"data": {},
"errors": []
}schema_versionbumps only on breaking changes — additive fields are always safe.errorsis always present; non-empty meanssuccess: false.- A non-zero exit code always accompanies
success: false.
Pass all parameters as a single flat JSON object. Keys use underscores (hyphens converted). The object merges over any CLI flags already provided.
bbackup restore \
--input-json '{"backup_path":"/tmp/bbackup/backup_20260227","containers":["myapp"],"dry_run":true}' \
--output jsonUnknown keys are silently ignored — forward-compatible by design.
bbackup backup --containers myapp --dry-run --output json{
"schema_version": "1",
"command": "backup",
"success": true,
"data": {
"dry_run": true,
"would_backup": {
"containers": ["myapp"],
"filesystem_targets": [],
"remotes": [],
"incremental": false,
"scope": {"volumes": true, "configs": true, "networks": true}
}
},
"errors": []
}| Code | Meaning |
|---|---|
0 |
Fully successful |
1 |
Bad argument, missing param, or invalid --input-json |
2 |
Config not found or fails validation |
3 |
Docker unreachable, rsync/rclone missing, or key generation failed |
4 |
Partial: some items succeeded, some failed |
5 |
Operation cancelled by user or agent |
Tip
For agent workflows, set BBACKUP_OUTPUT=json and BBACKUP_NO_INTERACTIVE=1 globally, then use bbackup skills to discover what's available before issuing commands.
Two modes are available:
Symmetric — AES-256-GCM: One key encrypts and decrypts. Good for single-server setups.
bbackup init-encryption --method symmetricAsymmetric — RSA-4096: Public key encrypts, private key decrypts. Better for multi-server setups where backup and restore run on separate machines.
bbackup init-encryption --method asymmetric --algorithm rsa-4096The public key can live on GitHub:
encryption:
enabled: true
method: asymmetric
asymmetric:
public_key: github:YOUR_USERNAME/gist:YOUR_GIST_ID
private_key: ~/.config/bbackup/backup_private.pemFull details in docs/encryption.md.
| Key | Action |
|---|---|
Q |
Quit / cancel backup |
P |
Pause / resume |
S |
Skip current item |
H |
Help |
best-backup/
├── bbackup/
│ ├── cli.py # bbackup CLI entry point
│ ├── cli_utils.py # JSON envelope, exit codes, shared decorators
│ ├── skills.py # Skill descriptors for agent discovery
│ ├── config.py # Config loading and all dataclasses
│ ├── docker_backup.py # Docker backup via temp Alpine containers
│ ├── filesystem_backup.py # Host filesystem backup via rsync
│ ├── backup_runner.py # Backup workflow orchestration
│ ├── restore.py # Restore operations
│ ├── tui.py # Rich TUI and BackupStatus tracking
│ ├── remote.py # Remote storage (local / rclone / SFTP)
│ ├── rotation.py # Retention policies and quota cleanup
│ ├── encryption.py # AES-256-GCM + RSA encryption
│ ├── logging.py # Rotating file logger
│ ├── bbman_entry.py # Console script shim for bbman
│ └── management/ # bbman subpackage (11 modules)
├── bbackup.py # bbackup entry point
├── bbman.py # bbman entry point
├── config.yaml.example # Annotated config template
├── pyproject.toml
└── uv.lock
| Doc | Description |
|---|---|
| QUICKSTART.md | Setup to first backup in 5 minutes |
| INSTALL.md | All installation methods |
| docs/management.md | Full bbman reference |
| docs/encryption.md | Encryption setup and key management |
| CHANGELOG.md | Release history |
| CONTRIBUTING.md | How to contribute |
| SECURITY.md | How to report vulnerabilities |
| SUPPORT.md | Where to ask questions or get help |
| docs/cli-skills.md | Unified CLI skills catalog for humans and AI agents |
| docs/VERSIONING.md | Version source of truth, hook setup, and release validation |
| docs/PUBLISHING_CHECKLIST.md | GitHub publishing and release readiness checklist |
Shipped
- Rich TUI with real-time transfer metrics
- Incremental backups with rsync
--link-dest - Backup rotation and retention policies
- AES-256-GCM and RSA-4096 encryption
- Full restore with optional rename
- Filesystem backup for arbitrary host paths and directory trees
- Management wrapper (
bbman) - GitHub key integration for public key distribution
- AI agent JSON I/O, skill discovery,
--dry-run, and--input-jsonon all commands - Backup manifest verification with SHA-256 hashes
- Temp-to-final upload promotion for local, SFTP, and rclone remotes
Planned
- Email and webhook notifications
- Cron-based scheduling integration
- Multi-server backup coordination
- Backup diff / comparison
- Web UI
Built with Rich, Click, and docker-py.
Slavic Kozyuk
© 2026 Crux Experts LLC — MIT License
