v0.4.5 — now on crates.io

Encrypted backups.
Synced everywhere.

Vivo 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.

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, rustfs, 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

Backblaze B2

Cost-effective cold storage via the b2 CLI. Uses b2 sync with automatic replacement of stale files. No remote restic repo initialization needed.

b2:my-bucket:restic/main

Quick Start

Up and running
in four commands.

Initialize vivo

Checks prerequisites and scaffolds your config and secrets files.

$ vivo init

Edit your config

Set your repo path, directories to back up, and remote destinations.

$ vivo config edit

Add your secrets

Set your restic password and 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.