From 81838b44b6013c0aeee17881e9d5ce0d29e947ba Mon Sep 17 00:00:00 2001 From: Matt Speer Date: Sat, 3 Oct 2026 09:36:30 -0500 Subject: [PATCH] Removed duplicate vw_backup.sh file and instead updated vaultwarden_backup.sh with new script to enable reliable backups. --- vaultwarden_backup.sh | 136 ++++++++++++++++++++++-------------------- vw_backup.sh | 110 ---------------------------------- 2 files changed, 71 insertions(+), 175 deletions(-) delete mode 100644 vw_backup.sh diff --git a/vaultwarden_backup.sh b/vaultwarden_backup.sh index 68e9f2f..7fcac99 100644 --- a/vaultwarden_backup.sh +++ b/vaultwarden_backup.sh @@ -2,12 +2,12 @@ # ============================================================================== # Script: vaultwarden_backup.sh -# Description: This script securely backs up Vaultwarden to a designated -# mounted drive using rsync. It includes pre-run checks to ensure -# the source files and destination are valid, and sends ntfy -# notifications for each task. +# Description: Backs up Vaultwarden (SQLite DB, RSA keys, attachments, +# sends, and config) to a mounted drive using Vaultwarden's +# native backup command via Docker exec and rsync. # Usage: sudo ./vaultwarden_backup.sh -# Notes: This script may require sudo/root privileges to access files. +# Notes: Must be run with root/sudo privileges to access Docker socket +# and host directories. # ============================================================================== # ============================================================================== @@ -16,8 +16,9 @@ BACKUP_MOUNT_POINT="/mnt/5TB-Disk1" BACKUP_DESTINATION="$BACKUP_MOUNT_POINT/backup" -# Vaultwarden backup directories -VAULTWARDEN_SOURCE_DIR="/srv/docker/vaultwarden/data" +# Vaultwarden settings +CONTAINER_NAME="vaultwarden" +VAULTWARDEN_DATA_DIR="/srv/docker/vaultwarden/data" VAULTWARDEN_DESTINATION="$BACKUP_MOUNT_POINT/backup/services/vaultwarden" # ntfy Notification Configuration @@ -26,79 +27,84 @@ NTFY_SERVER="https://ntfy.speerfam.net" NTFY_TOKEN="tk_3xo9mejjtgemyowzckqw2souo3mux" # ============================================================================== -# Pre-flight Checks (for the destination drive) +# Pre-flight Checks # ============================================================================== + +# Check if the mount point directory exists and is a mounted filesystem. if ! mountpoint -q "$BACKUP_MOUNT_POINT"; then echo "Error: '$BACKUP_MOUNT_POINT' is not a mount point. Please ensure the drive is mounted." >&2 curl -H "Authorization: Bearer $NTFY_TOKEN" -d "Error: Script failed. Destination '$BACKUP_MOUNT_POINT' is not mounted." "$NTFY_SERVER/$NTFY_TOPIC" > /dev/null 2>&1 exit 1 fi -# Check if the Vaultwarden source directory exists. -if [ ! -d "$VAULTWARDEN_SOURCE_DIR" ]; then - echo "Error: Vaultwarden backup source directory '$VAULTWARDEN_SOURCE_DIR' not found." >&2 - curl -H "Authorization: Bearer $NTFY_TOKEN" -d "Error: Script failed. Vaultwarden backup source not found." "$NTFY_SERVER/$NTFY_TOPIC" > /dev/null 2>&1 +# Check if the Vaultwarden source directory exists on the host. +if [ ! -d "$VAULTWARDEN_DATA_DIR" ]; then + echo "Error: Vaultwarden source directory '$VAULTWARDEN_DATA_DIR' not found." >&2 + curl -H "Authorization: Bearer $NTFY_TOKEN" -d "Error: Script failed. Vaultwarden data directory '$VAULTWARDEN_DATA_DIR' not found." "$NTFY_SERVER/$NTFY_TOPIC" > /dev/null 2>&1 exit 1 fi -# ============================================================================== -# Vaultwarden backup -# ============================================================================== -echo "Starting Vaultwarden backup process..." - -# Step 1: Clean up any existing database dump files before generating a new one -echo "Cleaning up old local database backup dumps..." -rm -f "$VAULTWARDEN_SOURCE_DIR"/db_*.sqlite3 - -# Step 2: Execute the Docker command to create the new database backup. -# Note: Removed '-it' flags so this executes properly under automated cron jobs. -echo "Running Vaultwarden backup via Docker..." -sudo docker exec vaultwarden /vaultwarden backup -if [ $? -ne 0 ]; then - echo "Error: Docker command failed to create Vaultwarden database backup." >&2 - curl -H "Authorization: Bearer $NTFY_TOKEN" -d "Error: Docker command failed to create Vaultwarden database backup." "$NTFY_SERVER/$NTFY_TOPIC" > /dev/null 2>&1 +# Check if the Docker container is running. +if ! docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then + echo "Error: Docker container '$CONTAINER_NAME' is not running." >&2 + curl -H "Authorization: Bearer $NTFY_TOKEN" -d "Error: Script failed. Docker container '$CONTAINER_NAME' is not running." "$NTFY_SERVER/$NTFY_TOPIC" > /dev/null 2>&1 exit 1 fi -echo "Vaultwarden database backup created successfully." -curl -H "Authorization: Bearer $NTFY_TOKEN" -d "Vaultwarden database backup created. Starting rsync." "$NTFY_SERVER/$NTFY_TOPIC" > /dev/null 2>&1 - -# Step 3: Rsync the Vaultwarden directories and files to the destination. -echo "Starting rsync of Vaultwarden data to '$VAULTWARDEN_DESTINATION'..." - -# Define source files/directories including the newly generated database dump file -VAULTWARDEN_SOURCES=( - "$VAULTWARDEN_SOURCE_DIR"/db_*.sqlite3 - "$VAULTWARDEN_SOURCE_DIR/attachments" - "$VAULTWARDEN_SOURCE_DIR/sends" - "$VAULTWARDEN_SOURCE_DIR/rsa_key.pem" - "$VAULTWARDEN_SOURCE_DIR/rsa_key.pub.pem" - "$VAULTWARDEN_SOURCE_DIR/icon_cache" -) - -# Ensure destination directory exists +# Ensure the destination directory exists. mkdir -p "$VAULTWARDEN_DESTINATION" -# Loop through each source and rsync it. -for source in "${VAULTWARDEN_SOURCES[@]}"; do - if [ -e "$source" ]; then - rsync -av --no-owner --no-group "$source" "$VAULTWARDEN_DESTINATION" - if [ $? -eq 0 ]; then - echo "Success: '$source' copied to '$VAULTWARDEN_DESTINATION'." - else - echo "Error: rsync failed to copy '$source'. Please check permissions." >&2 - curl -H "Authorization: Bearer $NTFY_TOKEN" -d "Error: rsync failed to copy Vaultwarden data." "$NTFY_SERVER/$NTFY_TOPIC" > /dev/null 2>&1 - exit 1 - fi - fi -done +# ============================================================================== +# Vaultwarden Backup Execution +# ============================================================================== +echo "Starting Vaultwarden backup via container exec..." -# Step 4: Clean up local database backup dump file to conserve space on primary disk -echo "Cleaning up temporary database backup dump from source directory..." -rm -f "$VAULTWARDEN_SOURCE_DIR"/db_*.sqlite3 +# Step 1: Trigger in-container database backup +docker exec "$CONTAINER_NAME" /vaultwarden backup +DB_STATUS=$? -echo "Success: Vaultwarden backup has been successfully copied to '$VAULTWARDEN_DESTINATION'." -curl -H "Authorization: Bearer $NTFY_TOKEN" -d "Success: Vaultwarden backup copied to $VAULTWARDEN_DESTINATION" "$NTFY_SERVER/$NTFY_TOPIC" > /dev/null 2>&1 +if [ $DB_STATUS -ne 0 ]; then + echo "Error: Vaultwarden docker exec backup failed with exit code $DB_STATUS." >&2 + curl -H "Authorization: Bearer $NTFY_TOKEN" -d "Error: Vaultwarden internal DB backup command failed." "$NTFY_SERVER/$NTFY_TOPIC" > /dev/null 2>&1 + exit 1 +fi -echo "All rsync tasks completed." -exit 0 \ No newline at end of file +# Step 2: Locate the newly generated database snapshot in the host data dir +LATEST_DB_BACKUP=$(ls -t "$VAULTWARDEN_DATA_DIR"/db_*.sqlite3 2>/dev/null | head -n 1) + +if [ -z "$LATEST_DB_BACKUP" ]; then + echo "Error: Could not locate generated db_*.sqlite3 backup file in '$VAULTWARDEN_DATA_DIR'." >&2 + curl -H "Authorization: Bearer $NTFY_TOKEN" -d "Error: Vaultwarden backup snapshot file missing after exec." "$NTFY_SERVER/$NTFY_TOPIC" > /dev/null 2>&1 + exit 1 +fi + +# Rsync the snapshot file to destination as db.sqlite3 +echo "Rsyncing database snapshot to '$VAULTWARDEN_DESTINATION/db.sqlite3'..." +rsync -av --no-owner --no-group "$LATEST_DB_BACKUP" "$VAULTWARDEN_DESTINATION/db.sqlite3" +RSYNC_DB_STATUS=$? + +if [ $RSYNC_DB_STATUS -ne 0 ]; then + echo "Error: rsync failed to copy database snapshot file." >&2 + curl -H "Authorization: Bearer $NTFY_TOKEN" -d "Error: rsync failed during Vaultwarden DB snapshot sync." "$NTFY_SERVER/$NTFY_TOPIC" > /dev/null 2>&1 + exit 1 +fi + +# Remove the temporary snapshot file from host source directory +rm -f "$LATEST_DB_BACKUP" + +# Step 3: Rsync remaining data (RSA keys, attachments, sends, config) excluding live db files +echo "Rsyncing attachments, RSA keys, and configuration files to '$VAULTWARDEN_DESTINATION'..." +rsync -av --no-owner --no-group --exclude='db.sqlite3*' "$VAULTWARDEN_DATA_DIR/" "$VAULTWARDEN_DESTINATION/" +RSYNC_DATA_STATUS=$? + +# ============================================================================== +# Completion and Notification +# ============================================================================== +if [ $RSYNC_DATA_STATUS -eq 0 ]; then + echo "Success: Vaultwarden database, keys, and attachments backed up to '$VAULTWARDEN_DESTINATION'." + curl -H "Authorization: Bearer $NTFY_TOKEN" -d "Success: Vaultwarden backup completed successfully to $VAULTWARDEN_DESTINATION" "$NTFY_SERVER/$NTFY_TOPIC" > /dev/null 2>&1 +else + echo "Error: rsync failed with exit code $RSYNC_DATA_STATUS. Check directory permissions." >&2 + curl -H "Authorization: Bearer $NTFY_TOKEN" -d "Error: rsync failed during Vaultwarden data backup." "$NTFY_SERVER/$NTFY_TOPIC" > /dev/null 2>&1 + exit 1 +fi \ No newline at end of file diff --git a/vw_backup.sh b/vw_backup.sh deleted file mode 100644 index 7fcac99..0000000 --- a/vw_backup.sh +++ /dev/null @@ -1,110 +0,0 @@ -#!/bin/bash - -# ============================================================================== -# Script: vaultwarden_backup.sh -# Description: Backs up Vaultwarden (SQLite DB, RSA keys, attachments, -# sends, and config) to a mounted drive using Vaultwarden's -# native backup command via Docker exec and rsync. -# Usage: sudo ./vaultwarden_backup.sh -# Notes: Must be run with root/sudo privileges to access Docker socket -# and host directories. -# ============================================================================== - -# ============================================================================== -# Define Variables for Source and Destination -# ============================================================================== -BACKUP_MOUNT_POINT="/mnt/5TB-Disk1" -BACKUP_DESTINATION="$BACKUP_MOUNT_POINT/backup" - -# Vaultwarden settings -CONTAINER_NAME="vaultwarden" -VAULTWARDEN_DATA_DIR="/srv/docker/vaultwarden/data" -VAULTWARDEN_DESTINATION="$BACKUP_MOUNT_POINT/backup/services/vaultwarden" - -# ntfy Notification Configuration -NTFY_TOPIC="Server" -NTFY_SERVER="https://ntfy.speerfam.net" -NTFY_TOKEN="tk_3xo9mejjtgemyowzckqw2souo3mux" - -# ============================================================================== -# Pre-flight Checks -# ============================================================================== - -# Check if the mount point directory exists and is a mounted filesystem. -if ! mountpoint -q "$BACKUP_MOUNT_POINT"; then - echo "Error: '$BACKUP_MOUNT_POINT' is not a mount point. Please ensure the drive is mounted." >&2 - curl -H "Authorization: Bearer $NTFY_TOKEN" -d "Error: Script failed. Destination '$BACKUP_MOUNT_POINT' is not mounted." "$NTFY_SERVER/$NTFY_TOPIC" > /dev/null 2>&1 - exit 1 -fi - -# Check if the Vaultwarden source directory exists on the host. -if [ ! -d "$VAULTWARDEN_DATA_DIR" ]; then - echo "Error: Vaultwarden source directory '$VAULTWARDEN_DATA_DIR' not found." >&2 - curl -H "Authorization: Bearer $NTFY_TOKEN" -d "Error: Script failed. Vaultwarden data directory '$VAULTWARDEN_DATA_DIR' not found." "$NTFY_SERVER/$NTFY_TOPIC" > /dev/null 2>&1 - exit 1 -fi - -# Check if the Docker container is running. -if ! docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then - echo "Error: Docker container '$CONTAINER_NAME' is not running." >&2 - curl -H "Authorization: Bearer $NTFY_TOKEN" -d "Error: Script failed. Docker container '$CONTAINER_NAME' is not running." "$NTFY_SERVER/$NTFY_TOPIC" > /dev/null 2>&1 - exit 1 -fi - -# Ensure the destination directory exists. -mkdir -p "$VAULTWARDEN_DESTINATION" - -# ============================================================================== -# Vaultwarden Backup Execution -# ============================================================================== -echo "Starting Vaultwarden backup via container exec..." - -# Step 1: Trigger in-container database backup -docker exec "$CONTAINER_NAME" /vaultwarden backup -DB_STATUS=$? - -if [ $DB_STATUS -ne 0 ]; then - echo "Error: Vaultwarden docker exec backup failed with exit code $DB_STATUS." >&2 - curl -H "Authorization: Bearer $NTFY_TOKEN" -d "Error: Vaultwarden internal DB backup command failed." "$NTFY_SERVER/$NTFY_TOPIC" > /dev/null 2>&1 - exit 1 -fi - -# Step 2: Locate the newly generated database snapshot in the host data dir -LATEST_DB_BACKUP=$(ls -t "$VAULTWARDEN_DATA_DIR"/db_*.sqlite3 2>/dev/null | head -n 1) - -if [ -z "$LATEST_DB_BACKUP" ]; then - echo "Error: Could not locate generated db_*.sqlite3 backup file in '$VAULTWARDEN_DATA_DIR'." >&2 - curl -H "Authorization: Bearer $NTFY_TOKEN" -d "Error: Vaultwarden backup snapshot file missing after exec." "$NTFY_SERVER/$NTFY_TOPIC" > /dev/null 2>&1 - exit 1 -fi - -# Rsync the snapshot file to destination as db.sqlite3 -echo "Rsyncing database snapshot to '$VAULTWARDEN_DESTINATION/db.sqlite3'..." -rsync -av --no-owner --no-group "$LATEST_DB_BACKUP" "$VAULTWARDEN_DESTINATION/db.sqlite3" -RSYNC_DB_STATUS=$? - -if [ $RSYNC_DB_STATUS -ne 0 ]; then - echo "Error: rsync failed to copy database snapshot file." >&2 - curl -H "Authorization: Bearer $NTFY_TOKEN" -d "Error: rsync failed during Vaultwarden DB snapshot sync." "$NTFY_SERVER/$NTFY_TOPIC" > /dev/null 2>&1 - exit 1 -fi - -# Remove the temporary snapshot file from host source directory -rm -f "$LATEST_DB_BACKUP" - -# Step 3: Rsync remaining data (RSA keys, attachments, sends, config) excluding live db files -echo "Rsyncing attachments, RSA keys, and configuration files to '$VAULTWARDEN_DESTINATION'..." -rsync -av --no-owner --no-group --exclude='db.sqlite3*' "$VAULTWARDEN_DATA_DIR/" "$VAULTWARDEN_DESTINATION/" -RSYNC_DATA_STATUS=$? - -# ============================================================================== -# Completion and Notification -# ============================================================================== -if [ $RSYNC_DATA_STATUS -eq 0 ]; then - echo "Success: Vaultwarden database, keys, and attachments backed up to '$VAULTWARDEN_DESTINATION'." - curl -H "Authorization: Bearer $NTFY_TOKEN" -d "Success: Vaultwarden backup completed successfully to $VAULTWARDEN_DESTINATION" "$NTFY_SERVER/$NTFY_TOPIC" > /dev/null 2>&1 -else - echo "Error: rsync failed with exit code $RSYNC_DATA_STATUS. Check directory permissions." >&2 - curl -H "Authorization: Bearer $NTFY_TOKEN" -d "Error: rsync failed during Vaultwarden data backup." "$NTFY_SERVER/$NTFY_TOPIC" > /dev/null 2>&1 - exit 1 -fi \ No newline at end of file