Skip to content

Latest commit

 

History

History
206 lines (147 loc) · 10.4 KB

QUICKSTART.md

File metadata and controls

206 lines (147 loc) · 10.4 KB

Your first backup and verified restore

This guide covers v2.0.6 and its schema-3 policy, including the issue #30 maintenance and compact-terminal changes below. Version 2.0.6 retains the v2.0.5 tested support scope; check the GitHub Releases page for tag and download availability. For an older v2.0.2 installation, use its versioned quick start until you migrate. Keep an independently retrievable copy of each repository password.

Start with the guided dashboard

Install Python 3.12+, uv, and restic, then use the development environment described in INSTALL.md:

uv sync --locked
uv run bbackup production tui

Setup walks through four short steps:

  1. Sources: choose an existing folder and name the backup job. Hidden files are included.
  2. Encrypted storage: choose a local repository and password-file path. An additional local repository is optional. Setup creates missing password files privately after review.
  3. Schedule: choose a systemd calendar expression and the maximum seconds for each capture or copy. The default is daily and 3,600 seconds per stage.
  4. Review and enroll: approve the source and storage mappings for this machine and user. Existing configuration files are never replaced.

Every field has a persistent label. Hover for help, or focus a field and press F1. Invalid inputs stay in the form so you can correct them. Advanced JSON remains available.

From Overview, choose Set up storage. Initialize the local repository first; initialize an optional replica with the local repository as its source. Choose Run first backup, review the selected job, and run it once. After success, select a snapshot and choose Restore with a new absolute destination folder.

Important

A second directory on the same host does not establish independent host-loss recovery. Copy repository passwords to independently retrievable encrypted or offline storage. Never store the only password copy inside the repository it unlocks.

Prefer the command line?

These commands use the same enrolled default configuration as the dashboard:

uv run bbackup production doctor
uv run bbackup production repositories init --name local
uv run bbackup production jobs run --name daily

If you configured the optional replica, initialize it before running the job:

uv run bbackup production repositories init --name replica --source local

Keep the full snapshot IDs returned by successful capture and copy operations. A local capture can succeed while a replica fails; the command returns a nonzero result with each destination's outcome. Inspect failed or uncertain targets before another attempt.

Check the replica, then restore its full snapshot ID into a new folder:

uv run bbackup production repositories check --name replica
uv run bbackup production restore --repository replica \
  --snapshot FULL_DESTINATION_SNAPSHOT_ID --target "$HOME/restore-test"

The restore target must not exist or overlap source, repository, password, or state paths. File verification does not prove application startup or complete machine recovery.

Policy you can move, bindings that stay private

Schema 3 keeps source identity and job intent in portable policy:

{
  "schema_version": 3,
  "repositories": [{"name": "local", "role": "local"}],
  "sources": [{"name": "documents", "kind": "files"}],
  "jobs": [{"name": "daily", "repository": "local", "sources": ["documents"], "schedule": "daily", "timeout_seconds": 3600}]
}

Private bindings resolve those names to actual paths and credential-file references. This example is illustrative; replace each path with an absolute path for the executing account:

{
  "schema_version": 3,
  "state_dir": "/private/state/bbackup",
  "repositories": {
    "local": {"repository": "/backup/local", "password_file": "/private/keys/local.password"}
  },
  "source_bindings": {"documents": {"paths": ["/srv/documents"]}}
}

Bindings and password files must be owner-only. Enrollment binds the exact policy and bindings to this machine and user. Copying them to another machine does not authorize execution there. Validated dashboard/CLI saves refresh enrollment automatically; manual edits require one explicit review and enrollment:

uv run bbackup production service enroll

For noninteractive new setup, supply reviewed candidate files using setup --configuration-file POLICY --bindings-file BINDINGS. This enrolls the candidates but does not initialize repositories or activate a schedule.

Migrate an existing schema-2 configuration

Open the dashboard with the existing paths and choose Migrate and enroll, or run:

uv run bbackup production --config config.json --bindings bindings.json config migrate

Migration writes enrolled sibling config.v3.json and bindings.v3.json files. Original bytes remain untouched. Use the returned paths for explicitly named configurations. The default-path workflow recognizes a valid locally enrolled migrated pair on later launches.

Apply a schedule deliberately

Render the selected job's units for review:

uv run bbackup production service render --name daily \
  --executable "$PWD/.venv/bin/bbackup"

Install the reviewed user-level units and activate their exact timer:

uv run bbackup production service install --name daily \
  --executable "$PWD/.venv/bin/bbackup" --activate

Units are installed under an absolute $XDG_CONFIG_HOME/systemd/user, or ~/.config/systemd/user when that variable is unset or relative. Use the same configuration environment as your user systemd manager. Parent traversal and symbolic-link ancestors are refused.

Omit --activate to install disabled units. The command never enables lingering, installs a system-wide service, or elevates privileges. User timers require an available user systemd manager; boot operation may require administrator-managed lingering. A differing existing unit is preserved for review. Installation documents qualification limits.

The experimental reviewed Linux coverage workflow adds explicit private scope discovery, review and drift checks, plus an experimental manual PostgreSQL covered-capture path. PostgreSQL coverage requires an externally coordinated administrative window and a manual confirmation flag; scheduled covered PostgreSQL jobs remain blocked. Its service render-system command renders root-controlled system units for administrator review; it never installs them. A complete scope check does not qualify complete-machine disaster recovery.

Persistent timers can catch up after an idle interruption. An interrupted mutation remains uncertain and blocks automatic replay until explicit reconciliation. Retention remains a separate reviewed action; scheduling does not silently prune data.

Review local retention and stale locks in v2.0.6

Version 2.0.6 includes the following maintenance features for issue #30, while retaining the v2.0.5 tested support scope. Use an explicitly enrolled policy and bindings; the examples below use the default configuration paths.

The v2.0.6 dashboard layout keeps forms and setup navigation reachable in compact terminals. Use Tab and Shift+Tab to move between controls; the focused control scrolls into view. Use F1 for field help. The legacy live dashboard summarizes resource categories and keeps failures and cancel hints visible when there is not enough room for its full layout.

For a job's retention object, optional local_last and local_weekly counts default to zero (disabled). For example:

{"local_last": 12, "local_daily": 14, "local_weekly": 8}

The optional counts must be nonnegative integers; booleans and null are rejected. local_daily retains its positive-integer requirement. Restic keeps a snapshot when any enabled rule matches, within the existing host/job group. Review the resulting exact snapshot selection before applying it:

uv run bbackup production retention plan --job daily
uv run bbackup production retention apply --input-json \
  '{"job":"daily","plan_token":"EXACT_PLAN_TOKEN","approved":true}'

The plan token includes the counts, snapshot inventory and replica evidence. Changing them requires a new plan. Required replica obligations recorded at capture still apply after editing a job. This operation forgets selected local snapshots; it does not prune repository data or apply cloud retention.

For a suspected interrupted Restic lock, inspect first:

uv run bbackup production repositories locks --name local

Review the returned lock inventory and eligibility. Stop every external repository writer and keep them stopped throughout inspection and unlock. Only an exact, bounded set of this host's same-user locks with demonstrably absent processes can qualify. Then explicitly approve the current token:

uv run bbackup production repositories unlock-stale --input-json \
  '{"name":"local","plan_token":"EXACT_REVIEW_TOKEN","approved":true,"quiescent_window_confirmed":true}'

The service reinspects under its mutation lease, uses ordinary repository-wide Restic unlock (which cannot target individual lock IDs), and verifies no locks remain. It cannot prevent an external writer from starting, so the quiet window is essential. Live, foreign, changed, malformed or incomplete locks block removal. Never repeat an uncertain unlock; use the administrator reconciliation workflow. This is a deliberate maintenance action, not automatic lock cleanup.

Existing Docker and YAML users

The retained 1.x commands use their own configuration. Legacy Docker restores require unused container/volume names; bind-mounted container restoration is refused. SFTP requires a previously trusted host key. See legacy management and encryption compatibility.



Slavic Kozyuk
© 2026 Crux Experts LLC — MIT License