Skip to content

v1.0.0

Choose a tag to compare

@shellharbor shellharbor released this 27 Sep 18:39
· 10 commits to main since this release

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 .complete markers: 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: false

GNU 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_copies across independent destinations;
  • SHA-256 payload validation;
  • per-file SHA-256 hashes for regular archive entries;
  • optional Minisign detached signatures;
  • verify --quick and deep verify --full;
  • safe staged restore to a new or empty directory;
  • restore --pick for terminal-based version selection;
  • diff ID1 ID2 with 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 --confirm

This 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, and keep_monthly;
  • retention.max_age_days for automatic expiry;
  • retention.min_keep, which protects the newest completed recovery copies;
  • pin and unpin markers for migration or incident recovery points;
  • date-range delete with dry-run planning and explicit --confirm;
  • local and remote deletion that removes .complete first.

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 26

It 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:

  1. Run backfort.sh -c /etc/backfort/config.yaml doctor.
  2. Create a backup and run verify --full.
  3. Rehearse a staged restore on a disposable host or directory.
  4. For Compose workloads, test restore-compose against a separate target project.
  5. 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.