Goal

Create a backup solution using restic that’s reliable, secure, and automated.

  • A desktop-turned server (debian) with ~10TB of storage

  • An offsite raspberry pi (dietpi) with a USB external HDD (3.5TB)

  • An account with Backblaze B2 for s3-compatible storage

  • Server -> Pi - Offsite backup for things I could lose without crying

  • Server -> B2 - Cloud backups for things I absolutely cannot lose

All credentials and things necessary to restore/recover/move this setup will be stored in Bitwarden.

Context

On the server I have two directories I care about with the following structure:

Note

  • (^) = Wanted Pi
  • (*) = Critical Pi and B2
  1. /zpool1/
    • archive/ ^
    • library/
      • books/ ^
      • books-comics/
      • games/
      • immich/ *
      • isos/
      • manual/
      • movies/
      • music/ ^
      • recordings/ *
      • software/
      • tv/
  2. /srv/docker/ *
    • <service-name>/
      • data/
      • config/

Solution

  1. Install restic.
  2. Configure restic to access the PI and B2.
    • Use a password file for security
    • Access the Pi over SSH (Tailscale) and restic’s SFTP backend.
    • Access B2 using restic’s s3-compatible backend.
  3. Create repo(s) on the Pi and in B2.
    • One for library
    • One for archive
    • One for docker
  4. Create script(s) to automate the process of backing up and reporting.
    • Requirements
      • Configurable variables
      • Error-handling
      • Log file
    • Structure
      • A configuration file with paths and settings
      • A primary backup script that sources this config
      • A separate status/reporting script
    • Restic
      • Use--exclude and/or --files-from to save space
      • Use check and prune to verify/clean up snapshots
    • Notifications to NTFY (using email or NTFY API)
  5. Automate the script(s) to run on it’s own

References


Log

Installation

Install Restic on the server

sudo apt update # Update package lists
sudo apt install restic # Install restic
 
###
 
restic version # Confirm installation
> restic 0.14.0 compiled with go1.19.8 on linux/amd64

Configuration

Configure server/restic to access the Pi and B2

# On the server, create directory for configuring restic
sudo mkdir -p /opt/restic/{config,scripts}
sudo chown -R $UID:$GID /opt/restic
sudo chmod -R 600 /opt/restic/config
sudo chmod -R 700 /opt/restic/scripts
 
# Create password file
bash -c 'echo "YourSuperSecretPasswrod" > /opt/restic/config/password'

Configure SSH access to the Pi

# Generate a specific SSH key for restic use
# Use defaults, no password, 
# Save the file in `/opt/restic/config/ssh`
ssh-keygen -t ed25519 -C "restic@srv01"
 
# Copy the key to the Pi
ssh-copy-id <user>@<pi-tailscale-ip>
 
# Confirm SSH connection
ssh <user>@<pi-tailscale-ip>

Configure B2 S3-compatible storage

Create S3-Compatible App Keys using Cloud Storage Application Keys

# Store B2 credentials
 
# For restic's Amazon S3 backend with B2 S3-compatible API (recommended)
bash -c 'echo "export AWS_ACCESS_KEY_ID=<b2-app-key>" > /opt/restic/config/b2-env-s3'
bash -c 'echo "export AWS_SECRET_ACCESS_KEY=<b2-key-id>" >> /opt/restic/config/b2-env-s3'
chmod 600 /opt/restic/config/b2-env-s3
 
# For restic's native B2 backend (not-recommended)
# bash -c 'echo "export B2_ACCOUNT_ID=your_account_id" > /opt/restic/config/b2-env'
# bash -c 'echo "export B2_ACCOUNT_KEY=your_account_key" >> /opt/restic/config/b2-env'
# chmod 600 /opt/restic/config/b2-env

Initialize Repos

# Initialize a repo on the Pi
restic -r sftp:<user>@<pi-tailscale-ip>:/path/to/backups/<repo-name> --password-file /opt/restic/config/password init
 
# Verify creation
restic -r sftp:<user>@<pi-tailscale-ip>:/path/to/backups/<repo-name> --password-file /opt/restic/config/password snapshots
 
 
# Initialize a repo on B2
source /opt/restic/config/b2-env-s3
export RESTIC_PASSWORD_FILE=/opt/restic/config/password # another way to set the password file
restic -r s3:s3.<region>.backblazeb2.com/<bucket>/<repo> init

The script

The head

 

The body