v0.11.2 — now on crates.io

Encrypted backups.
Synced everywhere.

vivo·keep wraps restic to orchestrate backups with multi-remote sync — S3, B2, and more. Credentials stay encrypted at rest with SOPS + age.

$ curl -sSf https://raw.githubusercontent.com/dantuck/vivo/main/install.sh | sh

How it works

One command.
Four phases.

1

Backup

restic snapshots your directories to a local repository

2

Check

repo integrity is verified before any remote sync

3

Forget

old snapshots are pruned by your retention policy

4

Sync

data is pushed to all configured remote backends

Features

Everything restic
was missing.

Credentials encrypted at rest

SOPS + age keeps your remote keys out of plaintext configs. Secrets are decrypted in-memory only at runtime.

Multi-remote sync

Push the same backup to S3, Backblaze B2, MinIO, and more in one run. Add as many remotes as you need.

Step control

Use --start-step to skip already-completed phases. Resume from forget, or run sync-only.

Self-updating

Run `vivo update` to pull the latest release. Background version checks notify you after each run.

Task chaining

Tasks can call other tasks and run shell commands post-backup. Circular references are detected and skipped.

Dry-run mode

Test your full configuration without writing a single byte. Skips remote sync, forwards --dry-run to restic.

Health checks

Run `vivo doctor` to verify that required tools are installed, your config and secrets are valid, and all remotes are reachable. Run `vivo doctor --fix` to auto-install any missing dependencies — no manual tool setup required.

Interactive TUI

Run `vivo manage` to open a full-screen config manager. Add, edit, and delete tasks, remotes, and call chains interactively. Set the default task with a keystroke — no manual KDL editing required.

Browse backups as files

Run `vivo mount` to explore any local or remote backup repo as a FUSE filesystem. Navigate snapshots, find individual files, and restore without touching restic directly.

Changelog

What's new.

v0.11.22026-07-04

Bug Fixes

  • **build:** use classic linker for aarch64-apple-darwin
v0.11.12026-07-04

Bug Fixes

  • **ci:** upgrade release-please-action to v5 for native node24 support
v0.11.02026-06-10

Features

  • **config:** expose mc-max-workers and mc-limit-upload in editor and TUI
  • **remote/rustfs:** add mc-max-workers and mc-limit-upload throttle options
v0.10.12026-06-08

Bug Fixes

  • **remote/rustfs:** auto-create bucket before sync if missing
v0.10.02026-06-08

Features

  • **doctor:** add --fix flag, update run_doctor signature
  • **doctor:** add fix_s3_sync_tool() with mc install and plain-doctor hint
  • **doctor:** add rustfs connectivity check via aws s3 ls
  • **doctor:** check mc/aws/rclone tool for s3/rustfs remotes
  • **remote:** add RustfsBackend with URL parsing
  • **remote:** add tool detection (mc/aws/rclone) to RustfsBackend
  • **remote:** implement RustfsBackend sync via mc/aws/rclone
  • **tui:** warn when adding s3/rustfs remote without mc/aws/rclone installed

Bug Fixes

  • **doctor:** re-run full doctor after fix, use mc for rustfs connectivity check
  • **remote:** pass credentials via env vars to avoid argv exposure in mc/rclone
  • **remote:** stream S3Backend sync output to terminal
  • **remote:** verify repo before destructive sync, scope s3-tool check to rustfs only, make connectivity check tool-aware

Configuration

KDL config.
Human-readable.

Configure backups in a clean KDL file. Set your repo, directories to back up, retention policy, and remote destinations — all in one place.

Secrets are stored separately in a SOPS-encrypted YAML file and injected as environment variables at runtime — never written to disk in plaintext.

Default config path ~/.config/vivo/backup.kdl
Default secrets path ~/.config/vivo/secrets.yaml
backup.kdl
// default task to run
default-task "backup"

tasks {
    task "backup" {
        backup {
            repo "$HOME/.local/share/restic/main"
            directory "$HOME"
            exclude-file "$HOME/.config/vivo/excludes"

            retention {
                daily   7
                weekly  5
                monthly 12
                yearly  2
            }

            remote "s3:https://s3.amazonaws.com/my-bucket" {
                credentials "aws"
            }
            remote "b2:my-bucket:restic/main" {
                credentials "b2"
            }
        }

        command "notify-send 'Backup complete'"
    }
}

Remote Backends

Your data.
Your clouds.

S3-compatible

AWS S3, MinIO, or any S3-compatible endpoint. Uses restic copy for fast, verified transfer. Initialize the remote repo once before first sync.

s3:https://s3.amazonaws.com/my-bucket
Initialize once restic init --repo s3:https://s3.amazonaws.com/my-bucket

RustFS

Self-hosted S3-compatible object storage via the rustfs: prefix — perfect for home labs and private NAS setups. The bucket is created automatically on first sync. Set mc-max-workers and mc-limit-upload per remote to throttle uploads and avoid overwhelming your server.

rustfs:http://nas:9000/bucket
Initialize once restic init --repo rustfs:http://nas:9000/bucket

Backblaze B2

Cost-effective cold storage via the b2 CLI. Uses b2 sync with automatic replacement of stale files. Credentials are imported automatically and re-authorized on failure. No remote restic repo initialization needed.

b2:my-bucket:restic/main

Quick Start

Up and running
in five steps.

Initialize vivo

Checks prerequisites and scaffolds your config and secrets files.

$ vivo init

Add a backup task

Create a named task with its restic repo and the directory to back up. Or use vivo manage for an interactive TUI.

$ vivo task add --name main --repo ~/.local/share/restic/main --dir ~
$ vivo manage

Add remote destinations

Attach one or more remotes to a task — S3, RustFS, or Backblaze B2. Import S3/RustFS credentials first.

$ vivo secrets import-s3 --profile rustfs
$ vivo remote add --task main --url "rustfs:http://nas:9000/bucket" --credentials rustfs

Add your secrets

Set your restic password and any additional remote credentials, encrypted with SOPS + age.

$ vivo secrets edit

Run a backup

Dry-run first to verify your setup, then run the real backup.

$ vivo --dry-run
$ vivo

Install

Get vivo.

One-line install

Linux and macOS. Downloads the latest binary from GitHub Releases and verifies the SHA256 checksum.

$ curl -sSf https://raw.githubusercontent.com/dantuck/vivo/main/install.sh | sh

From Cargo

Requires Rust installed. Builds from source and installs to your Cargo bin directory.

$ cargo install vivo

Build from source

Clone from Codeberg or GitHub and build manually.

$ git clone https://codeberg.org/tuck/vivo
cd vivo
cargo build --release
cp target/release/vivo /usr/local/bin/

Already installed? Run vivo update to upgrade to the latest release, or vivo update --dry-run to preview without applying.