Repository navigation
v1.0.0
Backfort v1.0.0 — First Stable Release
Backfort 1.0.0 is the first stable release of a recovery-first backup tool for Linux.
It is a one-shot Bash utility: no resident daemon, no proprietary backend, and no hidden state outside the configured locations. Define backup policy in YAML, run it from cron or systemd, and restore only from complete, verified backup versions.
Highlights
- Reliable backups for files, Docker Compose projects, named volumes, bind mounts, and databases.
- Local storage plus any [rclone](https://rclone.org/) destination: S3-compatible storage, AWS S3, Cloudflare R2, DigitalOcean Spaces, Vultr Object Storage, Dropbox, Yandex Disk, pCloud, FTP/SFTP, and more.
- Atomic publication with
.completemarkers: incomplete copies are never presented as recoverable backups. - Full verification before recovery, including payload checksums and per-file archive hashes.
- Encryption with age, symmetric GPG, or asymmetric GPG public keys; optional Minisign signatures.
- Safe staged restore, interactive restore selection, Compose recovery assistance, retention, pins, notifications, Prometheus metrics, and a dead man's switch.
Backup sources
Files and directories
Back up one or more explicit paths with configurable exclude patterns and optional symlink following.
source:
type: files
paths:
- /etc
- /srv/www
exclude:
- '*.log'
- '*/cache/*'
follow_symlinks: falseGNU tar preserves numeric ownership, POSIX ACLs, extended attributes, sparse files, and timestamps for supported regular files.
Docker Compose projects
Backfort can create an explicit migration-grade backup of a Compose project:
- selected Compose and environment files;
- selected named volumes;
- selected bind-mounted project paths;
- logical PostgreSQL, MySQL, and MariaDB dumps;
- MS SQL Server native backup artifacts;
- Oracle Data Pump export artifacts.
Database volumes are never treated as a replacement for logical database dumps.
Named volumes are read by a short-lived helper container with:
- no network;
- read-only root filesystem;
- read-only source volume;
- no writable host mounts;
- all Linux capabilities dropped except
DAC_READ_SEARCH.
The helper streams its archive to Backfort, which writes it into its protected workspace.
Quick backups
For urgent work, no hand-written YAML is required:
backfort.sh quick /etc /srv/www/site \
--name before-deploy \
--to /var/backups/backfort \
--to rclone:cloudflare-r2:backfort/web-01 \
--min-copies 2 \
--exclude '*.log'quick-compose provides the same fast path for an explicit Compose project, selected volumes, bind mounts, and database dumps.
Storage, integrity, and recovery
Every published backup is a complete bundle with payload, metadata, checksum, optional signature, and a final .complete marker.
Backfort provides:
- atomic local and rclone publication;
- configurable
success.min_copiesacross independent destinations; - SHA-256 payload validation;
- per-file SHA-256 hashes for regular archive entries;
- optional Minisign detached signatures;
verify --quickand deepverify --full;- safe staged restore to a new or empty directory;
restore --pickfor terminal-based version selection;diff ID1 ID2with text and JSON output;- host-scoped automatic discovery in shared destinations.
A backup is never considered valid merely because an archive exists. It must have complete bundle evidence and pass validation.
Encryption and signing
Backfort supports:
- age encryption with one or multiple recipients;
- symmetric GPG encryption with protected passphrase handling;
- asymmetric GPG encryption using exact public-key fingerprints;
- recovery from a separate private-key host;
- optional protected private-key passphrase environment variables;
- Minisign payload signatures.
Configuration stores environment-variable names, never secret values. Backfort does not place credentials, passwords, tokens, or private keys into YAML, logs, manifests, generated recovery configuration, or notifications.
Compose recovery assistant
restore-compose restores and verifies a Compose backup into an explicit staging directory, then prints an actionable recovery plan.
For PostgreSQL, MySQL, and MariaDB, it can optionally import logical dumps into an already running target Compose project:
backfort.sh -c /etc/backfort/config.yaml \
restore-compose latest \
--job crm \
--to /srv/recovery/crm \
--project-dir /srv/crm-target \
--apply --confirmThis intentionally does not deploy project files, create or overwrite volumes, start services, restore data in place, apply PostgreSQL global roles, or guess MS SQL/Oracle recovery steps.
Retention and lifecycle controls
Backfort includes conservative cleanup controls:
- GFS-style
keep_last,keep_daily,keep_weekly, andkeep_monthly; retention.max_age_daysfor automatic expiry;retention.min_keep, which protects the newest completed recovery copies;pinandunpinmarkers for migration or incident recovery points;- date-range
deletewith dry-run planning and explicit--confirm; - local and remote deletion that removes
.completefirst.
Pinned backups remain outside normal retention and age-based expiry.
Operational visibility
Notifications
Unified event notifications support:
- Telegram;
- ntfy;
- generic webhooks;
- local SMTP.
Notifications support failure, success, partial-copy, recovery, prune, watchdog, and digest events. Templates use a fixed safe placeholder set, include restore hints, redact secrets, and keep delivery failures non-fatal.
Prometheus
Optional node_exporter textfile metrics expose per-job:
- latest success state;
- exit code;
- backup duration;
- payload size;
- successful and failed destination copies;
- completion timestamp.
Metrics files are written atomically with stable, low-cardinality labels.
Watchdog
Use watchdog as a dead man's switch to detect missing or stale recoverable backups:
backfort.sh -c /etc/backfort/config.yaml watchdog --job crm --max-age 26It validates the newest completed version instead of trusting file timestamps or incomplete uploads.
Hooks and automation
Per-job pre and post hooks support safe application quiescing, filesystem snapshots, and cleanup workflows.
Hooks use executable paths with literal argument arrays rather than shell command strings. Backfort validates ownership and permissions, supplies a scrubbed environment, bounds execution time, supports dry-run planning, and invokes post-cleanup after interrupted work where possible.
Schedule Backfort with cron or systemd; it deliberately does not run as a permanent daemon.
Safety model
Backfort 1.0.0 is designed to prefer a visible failure over an unsafe recovery assumption.
- Strict YAML validation rejects unknown or malformed configuration.
- Restore requires an explicit new or empty target directory.
- In-place overwrite is intentionally unsupported.
- Only explicitly configured files, volumes, bind mounts, and databases are included.
- Incomplete or malformed bundles are ignored by list, status, restore, retention, deletion, and watchdog operations.
- Shared destinations are isolated by
settings.host_id. - Preflight failures are observable through logs, metrics, and notifications.
- Remote publishing and deletion preserve commit-marker ordering.
Quality and project automation
The release is backed by automated checks for:
- Bash syntax and ShellCheck;
- Bash 4.3 runtime compatibility;
- configuration parsing and example validation;
- file, archive, retention, encryption, signing, notification, metrics, and watchdog behavior;
- local and rclone recovery paths;
- fake-Docker Compose coverage;
- real PostgreSQL, MySQL, and named-volume Compose recovery integration;
- restore fidelity for owners, ACLs, xattrs, and sparse files;
- GitHub documentation links;
- CodeQL, OpenSSF Scorecard, Dependabot, and release metadata validation.
Known boundaries
Backfort is intentionally not a backup server or a replacement for database-native high-availability tooling.
- It does not perform in-place restores.
- It does not infer what should be backed up from a Compose file or image.
- It does not automatically restore named volumes into a live deployment.
- MS SQL Server and Oracle artifacts require engine-specific operator-led recovery.
- Scheduling is delegated to cron or systemd.
- rclone provider credentials are configured outside Backfort.
Upgrade guidance
Before adopting v1.0.0 in production:
- Run
backfort.sh -c /etc/backfort/config.yaml doctor. - Create a backup and run
verify --full. - Rehearse a staged restore on a disposable host or directory.
- For Compose workloads, test
restore-composeagainst a separate target project. - Configure at least two independent destinations for important workloads.
Thank you to everyone who tested the early releases and helped turn Backfort into a dependable recovery tool.