In my installation - I use sqlite as databases. In addition to backing up the database itself, you need to make backup copies of the files themselves.

As my main backup repository, I use backblaze.

As a backup tool - restic. Mainly due to three features - support for different storage providers, incremental copying and encryption.

The most important thing is not to lose the encryption key, which must be defined in the RESTIC_PASSWORD variable. If you still lost - you can say goodbye to the backup.

To perform a backup, I created the following script and run every hour:

#!/bin/bash

set -e -o pipefail

mkdir -p /var/cache/restic

HOST=$(hostname -f)

export RESTIC_CACHE_DIR=/var/cache/restic
export RESTIC_PASSWORD=<my easy encryption password>
export RESTIC_REPOSITORY=b2:<my backblaze bucket name>:${HOST}/
export B2_ACCOUNT_ID=<my access code>
export B2_ACCOUNT_KEY=<my secret code>

KEEP_LAST=24
KEEP_DAILY=7
KEEP_WEEKLY=5
KEEP_MONTHLY=12

RESTIC_CMD="/usr/bin/restic"
RESTIC_BACKUP_CMD="flock --nonblock --conflict-exit-code 0 /run/restic-backup.lock ${RESTIC_CMD}"

mkdir -p /media/data/vaultwarden/backup
/usr/bin/find /media/data/vaultwarden/backup -type f -ctime +30 -delete

/usr/bin/sqlite3 /media/data/vaultwarden/data/db.sqlite3 ".backup '/media/data/vaultwarden/backup/db-$(date '+%Y%m%d-%H%M').sqlite3'"

if ! restic snapshots 2>&1 >/dev/null; then
  ${RESTIC_CMD} init
fi

${RESTIC_CMD} self-update >/dev/null 2>&1

${RESTIC_BACKUP_CMD} backup --one-file-system /media/data/vaultwarden >/dev/null 2>&1

${RESTIC_CMD} forget --prune \
    --keep-last=${KEEP_LAST} \
    --keep-daily=${KEEP_DAILY} \
    --keep-weekly=${KEEP_WEEKLY} \
    --keep-monthly=${KEEP_MONTHLY} >/dev/null 2>&1