diff --git a/common-backup.sh b/common-backup.sh new file mode 100755 index 0000000..8c20305 --- /dev/null +++ b/common-backup.sh @@ -0,0 +1,158 @@ +#!/bin/bash + +log() { + local message="$1" + echo "$(date '+%Y-%m-%d %H:%M:%S') - $message" | tee -a "$LOG_FILE" +} + +stop_container() { + local c="$1" + log "Stopping $c..." + docker stop "$c" || { log "Error stopping $c"; exit 1; } +} + +start_container() { + local c="$1" + log "Starting $c..." + docker start "$c" || { log "Error starting $c"; exit 1; } +} + +enable_maintenance_mode() { + local c="$1" + local cmd="$2" + log "Enabling maintenance mode for $c..." + # we explcitly do not want to stringify here + # shellcheck disable=SC2086 + docker exec -u www-data "$c" $cmd || { log "Error enabling maintenance mode"; exit 1; } +} + +disable_maintenance_mode() { + local c="$1" + local cmd="$2" + log "Disabling maintenance mode for $c..." + # we explcitly do not want to stringify here + # shellcheck disable=SC2086 + docker exec -u www-data "$c" $cmd || { log "Error disabling maintenance mode"; exit 1; } +} + +dump_postgres_db() { + local c="$1" + local user="$2" + local path="$3" + log "Dumping PostgreSQL db for $c..." + docker exec -t "$c" pg_dumpall --clean --if-exists --username="$user" --file="$path" || { log "Error dumping PostgreSQL"; exit 1; } +} + +dump_mariadb_db() { + local c="$1" + local user="$2" + local pass="$3" + local db="$4" + local path="$5" + log "Dumping MariaDB/MySQL db..." + docker exec "$c" mariadb-dump --single-transaction -h localhost -u "$user" -p"$pass" "$db" > "$path" || { log "Error dumping MariaDB/MySQL"; exit 1; } +} + +dump_sqlite_db() { + local src="$1" + local dst="$2" + log "Dumping SQLite db..." + sqlite3 "$src" ".backup $dst" || { log "Error dumping SQLite"; exit 1; } +} + +run_duplicati_backup() { + local dest="$1" + local name="$2" + local versions="$3" + local sftp_user="$4" + local sftp_pass="$5" + local fingerprint="$6" + local passphrase="$7" + shift 7 + local sources=("$@") + log "Running duplicati backup for $name..." + docker exec duplicati duplicati-cli backup "ssh://$dest" "${sources[@]}" \ + --backup-name="$name backup" \ + --keep-versions="$versions" \ + --auth-username="$sftp_user" \ + --auth-password="$sftp_pass" \ + --passphrase="$passphrase" \ + --ssh-fingerprint="$fingerprint" \ + --prefix="$name" || { log "Error in duplicati backup for $name"; exit 1; } + log "$name backup complete." +} + +tar_and_encrypt() { + local source_dir="$1" + local output_file="$2" + local passphrase="$3" + log "Compressing and encrypting $source_dir..." + sudo tar --absolute-names -czf - "$source_dir" | \ + openssl enc -aes-256-cbc -pbkdf2 -pass "pass:$passphrase" > "$output_file" || { + log "Error: Failed to create encrypted archive." + exit 1 + } +} + +scp_transfer() { + local local_file="$1" + local ssh_user="$2" + local ssh_host="$3" + local ssh_key="$4" + local ssh_port="$5" + local remote_path="$6" + log "Transferring $local_file to $ssh_user@$ssh_host:$remote_path" +<<<<<<< Updated upstream + scp -v -P "$ssh_port" -i "$ssh_key" "$local_file" \ +======= + scp -P "$ssh_port" -i "$ssh_key" "$local_file" \ +>>>>>>> Stashed changes + "$ssh_user@$ssh_host:$remote_path" || { + log "Error: Failed to transfer file." + exit 1 + } +} + +remove_old_backups() { + local ssh_user="$1" + local ssh_host="$2" + local ssh_key="$3" + local ssh_port="$4" + local backup_folder="$5" + local max_backups="$6" +<<<<<<< Updated upstream + log "Checking for old backups..." + local existing_backups + existing_backups=$(ssh -p "$ssh_port" -i "$ssh_key" "$ssh_user@$ssh_host" \ + "ls -1 $backup_folder | wc -l") || { + log "Error: Failed to count existing backups." + exit 1 + } + if (( existing_backups > max_backups )); then + log "Removing old backups..." + ssh -p "$ssh_port" -i "$ssh_key" "$ssh_user@$ssh_host" \ + "ls -t $backup_folder | tail -n +$((max_backups+1)) | xargs rm" || { + log "Error: Failed to remove old backups." + exit 1 + } +======= + log "Removing old backups..." + local existing_backups + existing_backups=$(ssh -p "$ssh_port" -i "$ssh_key" "$ssh_user@$ssh_host" \ + "ls -1 $backup_folder") || { + log "Error: Failed to count existing backups." + exit 1 + } + + files_to_delete=$(echo "$existing_backups" | sort -t'-' -k2 | head -n -$max_backups) + + if [[ ! -z "$files_to_delete" ]]; then + for file in $files_to_delete; do + ssh -p "$ssh_port" -i "$ssh_key" "$ssh_user@$ssh_host" \ + "rm -f $backup_folder$file" + done + else + echo "No files to delete" +>>>>>>> Stashed changes + fi +} diff --git a/cryptpad/cryptpad-backup.sh b/cryptpad/cryptpad-backup.sh index 590c68a..1f7e69c 100755 --- a/cryptpad/cryptpad-backup.sh +++ b/cryptpad/cryptpad-backup.sh @@ -1,48 +1,33 @@ #!/bin/bash -SCRIPT_ABS_LOCATION=$(realpath "$(dirname "${0}")") +SCRIPT_ABS_LOCATION=$(realpath "$(dirname "$0")") +# shellcheck disable=SC1090 +source "$SCRIPT_ABS_LOCATION/../common-backup.sh" # shellcheck disable=SC1090 source "$SCRIPT_ABS_LOCATION/cryptpad-backup.env" -# shellcheck disable=SC1090 -source "$SCRIPT_ABS_LOCATION/../logger.sh" - -# Container Names -CONTAINER="cryptpad" -BACKUP_CONTAINER="duplicati" - # shellcheck disable=SC2034 LOG_FILE="$SCRIPT_ABS_LOCATION/cryptpad-backup.log" -SOURCE_DIR="/mnt/data/cryptpad" +log "Cleaning up inactive files..." +docker exec "$APP_CONTAINER" /usr/local/bin/node scripts/evict-inactive.js --workdir=/cryptpad || { log "Error cleaning up inactive files"; exit 1; } -# Cleanup inactive and archive files -log "Cleaning up inactive accounts and files to save space..." -docker exec cryptpad \ - /usr/local/bin/node scripts/evict-inactive.js \ - --workdir=/cryptpad || { log "Error: Failed to clean up inactive files"; exit 1; } +log "Cleaning up archived files..." +docker exec "$APP_CONTAINER" /usr/local/bin/node scripts/evict-archived.js --workdir=/cryptpad || { log "Error cleaning up archived files"; exit 1; } -log "Cleaning up archived beyond retention period files to save space..." -docker exec cryptpad \ - /usr/local/bin/node scripts/evict-archived.js \ - --workdir=/cryptpad || { log "Error: Failed to clean up inactive files"; exit 1; } +run_duplicati_backup \ + "$BACKUP_DESTINATION" \ + "$APP_CONTAINER" \ + 7 \ + "$SFTP_USERNAME" \ + "$SFTP_PASSWORD" \ + "$SFTP_FINGERPRINT" \ + "$BACKUP_ENCR_PASSPHRASE" \ + "$SOURCE_DIR/data" \ + "$SOURCE_DIR/datastore" \ + "$SOURCE_DIR/block" \ + "$SOURCE_DIR/blob" \ + "$SOURCE_DIR/config/config.js" \ + "$SOURCE_DIR/customize" \ + "$SOURCE_DIR/customize.dist" -# Backup all files to target destination -log "Backing up cryptpad files and database..." -docker exec "$BACKUP_CONTAINER" \ - duplicati-cli backup "ssh://$BACKUP_DESTINATION" \ - "$SOURCE_DIR/data" \ - "$SOURCE_DIR/datastore" \ - "$SOURCE_DIR/block" \ - "$SOURCE_DIR/blob" \ - "$SOURCE_DIR/config/config.js" \ - "$SOURCE_DIR/customize" \ - "$SOURCE_DIR/customize.dist" \ - --backup-name="$CONTAINER backup" \ - --keep-versions=7 \ - --auth-username="$SFTP_USERNAME" \ - --auth-password="$SFTP_PASSWORD" \ - --passphrase="$BACKUP_ENCR_PASSPHRASE" \ - --ssh-fingerprint="$SFTP_FINGERPRINT" \ - --prefix="cryptpad" || { log "Error: Failed to backup cryptpad files and database."; exit 1; } -log "cryptpad backup completed successfully." diff --git a/duplicati/duplicati-backup.sh b/duplicati/duplicati-backup.sh index baf0a8f..de0a884 100755 --- a/duplicati/duplicati-backup.sh +++ b/duplicati/duplicati-backup.sh @@ -2,61 +2,78 @@ SCRIPT_ABS_LOCATION=$(realpath "$(dirname "${0}")") # shellcheck disable=SC1090 -source "$SCRIPT_ABS_LOCATION/duplicati-backup.env" - +source "$SCRIPT_ABS_LOCATION/../common-backup.sh" # shellcheck disable=SC1090 -source "$SCRIPT_ABS_LOCATION/../logger.sh" - -# Default values -SOURCE_DIR="/mnt/data/duplicati" -MAX_BACKUPS=7 -BACKUP_FOLDER="" -SSH_KEY="${SSH_KEY:-$HOME/.ssh/id_rsa}" +source "$SCRIPT_ABS_LOCATION/duplicati-backup.env" # shellcheck disable=SC2034 LOG_FILE="$SCRIPT_ABS_LOCATION/duplicati-backup.log" -# Override with command-line arguments -while getopts ":f:h:u:p:m:b:" opt; do - case $opt in - f) SOURCE_DIR="$OPTARG";; - h) SSH_DESTINATION="$OPTARG";; - u) SSH_USERNAME="$OPTARG";; - p) SSH_KEY="$OPTARG";; - m) MAX_BACKUPS="$OPTARG";; - b) BACKUP_FOLDER="$OPTARG";; - \?) echo "Invalid option: -$OPTARG"; exit 1;; - esac -done - -# Create a temporary file for the encrypted archive -TMP_FILENAME="duplicati_db-$(date +"%Y%m%d").bak" TMP_FILEPATH="$SCRIPT_ABS_LOCATION" if [ -z "$TMP_FILEPATH" ]; then - log "Error: TMP_FILEPATH is not set."; exit 1 + log "Error: TMP_FILEPATH is not set." + exit 1 fi -# Create the encrypted archive using tar and openssl -log "Compressing and excrypting the Duplicati Databases" -sudo tar --absolute-names -czf - "$SOURCE_DIR" | openssl enc -aes-256-cbc -pbkdf2 -pass "pass:$BACKUP_ENCR_PASSPHRASE" > "$TMP_FILEPATH/$TMP_FILENAME" || { log "Error: Failed to create encrypted archive."; exit 1; } +<<<<<<< Updated upstream +stop_container duplicati +tar_and_encrypt "$SOURCE_DIR" "$TMP_FILEPATH/$TMP_FILENAME" "$BACKUP_ENCR_PASSPHRASE" -# Connect to the backup host and count the number of existing backups -log "Fetching number of backups in destination folder" -EXISTING_BACKUPS=$(ssh "$SSH_USERNAME@$SSH_DESTINATION" -p 23 -i "$SSH_KEY" 'ls' | sudo wc -l) || { log "Error: Failed to count existing backups."; exit 1; } +remove_old_backups \ + "$SSH_USERNAME" \ + "$SSH_DESTINATION" \ + "$SSH_KEY" \ + "$SSH_PORT" \ + "$BACKUP_FOLDER" \ + "$MAX_BACKUPS" -# Remove old backups if there are too many -if (( EXISTING_BACKUPS > MAX_BACKUPS )); then - log "Removing old backups in order to save space" - ssh "$SSH_USERNAME@$SSH_DESTINATION" -p 23 -i "$SSH_KEY" "ls -t $BACKUP_FOLDER | tail -n +$((MAX_BACKUPS+1)) | xargs rm" || { log "Error: Failed to remove old backups."; exit 1; } -fi +scp_transfer \ + "$TMP_FILEPATH/$TMP_FILENAME" \ + "$SSH_USERNAME" \ + "$SSH_DESTINATION" \ + "$SSH_KEY" \ + "$SSH_PORT" \ + "${BACKUP_FOLDER}${TMP_FILENAME}" -# Transfer the encrypted archive to the backup host using scp -log "Transfering archive to SSH Destination" -scp -v -P 23 -i "$SSH_KEY" "$TMP_FILEPATH/$TMP_FILENAME" "$SSH_USERNAME@$SSH_DESTINATION:$BACKUP_FOLDER$TMP_FILENAME" || { log "Error: Failed to transfer the encrypted archive."; exit 1; } +log "Cleaning up temporary archive..." +rm "$TMP_FILEPATH/$TMP_FILENAME" || { + log "Error: Failed to remove the temporary file." + exit 1 +} -# Remove the temporary file -log "Cleaning up files" -rm "$TMP_FILEPATH/$TMP_FILENAME" || { log "Error: Failed to remove the temporary file."; exit 1; } +start_container duplicati -log "Backup completed successfully." +log "duplicati backup completed." +======= +remove_old_backups \ + "$SSH_USERNAME" \ + "$SSH_DESTINATION" \ + "$SSH_KEY" \ + "$SSH_PORT" \ + "$BACKUP_FOLDER" \ + "$MAX_BACKUPS" + +stop_container duplicati + +tar_and_encrypt "$SOURCE_DIR" "$TMP_FILEPATH/$TMP_FILENAME" "$BACKUP_ENCR_PASSPHRASE" + +scp_transfer \ + "$TMP_FILEPATH/$TMP_FILENAME" \ + "$SSH_USERNAME" \ + "$SSH_DESTINATION" \ + "$SSH_KEY" \ + "$SSH_PORT" \ + "${BACKUP_FOLDER}${TMP_FILENAME}" + +log "Cleaning up temporary archive..." +rm "$TMP_FILEPATH/$TMP_FILENAME" || { + log "Error: Failed to remove the temporary file." + exit 1 +} + +start_container duplicati + +log "duplicati backup completed." + +>>>>>>> Stashed changes diff --git a/forgejo/forgejo-backup.sh b/forgejo/forgejo-backup.sh index 4c6a245..9dfadc2 100755 --- a/forgejo/forgejo-backup.sh +++ b/forgejo/forgejo-backup.sh @@ -1,41 +1,25 @@ #!/bin/bash -SCRIPT_ABS_LOCATION=$(realpath "$(dirname "${0}")") +SCRIPT_ABS_LOCATION=$(realpath "$(dirname "$0")") +# shellcheck disable=SC1090 +source "$SCRIPT_ABS_LOCATION/../common-backup.sh" # shellcheck disable=SC1090 source "$SCRIPT_ABS_LOCATION/forgejo-backup.env" -# shellcheck disable=SC1090 -source "$SCRIPT_ABS_LOCATION/../logger.sh" - -# Container Names -APP_CONTAINER="forgejo" -BACKUP_CONTAINER="duplicati" - # shellcheck disable=SC2034 LOG_FILE="$SCRIPT_ABS_LOCATION/forgejo-backup.log" -SOURCE_DIR="/mnt/data/forgejo" +stop_container "$APP_CONTAINER" -# Stop forgejo container -log "Stopping forgejo container..." -docker stop $APP_CONTAINER || { log "Error: Failed to stop forgejo."; exit 1; } +run_duplicati_backup \ + "$BACKUP_DESTINATION" \ + "$APP_CONTAINER" \ + 7 \ + "$SFTP_USERNAME" \ + "$SFTP_PASSWORD" \ + "$SFTP_FINGERPRINT" \ + "$BACKUP_ENCR_PASSPHRASE" \ + "$SOURCE_DIR" -# Backup all files to target destination -log "Backing up forgejo files (including the SQLite database)..." -docker exec $BACKUP_CONTAINER \ - duplicati-cli backup \ - "ssh://$BACKUP_DESTINATION" \ - "$SOURCE_DIR" \ - --backup-name="forgejo backup" \ - --keep-versions=7 \ - --auth-username="$SFTP_USERNAME" \ - --auth-password="$SFTP_PASSWORD" \ - --passphrase="$BACKUP_ENCR_PASSPHRASE" \ - --ssh-fingerprint="$SFTP_FINGERPRINT" \ - --prefix="forgejo" || { log "Error: Failed to backup forgejo files and database."; exit 1; } +start_container "$APP_CONTAINER" -# Turn off Maintenance Mode -log "Starting forgejo container..." -docker start "$APP_CONTAINER" || { log "Error: Failed to start forgejo container."; exit 1; } - -log "Forgejo backup completed successfully." diff --git a/full-backup.sh b/full-backup.sh index 56b7202..bddb204 100755 --- a/full-backup.sh +++ b/full-backup.sh @@ -8,11 +8,12 @@ declare -a apps=("cryptpad" "immich" "duplicati" "nextcloud" "vaultwarden" "forg # Function to execute the backup script for each application backup_app() { local app=$1 - "$SCRIPT_ABS_LOCATION/$app/${app}-backup.sh" + "$SCRIPT_ABS_LOCATION/$app/$app-backup.sh" } # Iterate over each app in the array and call the backup function for app in "${apps[@]}"; do backup_app "$app" + sleep 5 done diff --git a/immich/immich-backup.sh b/immich/immich-backup.sh index 4e2568f..6554332 100755 --- a/immich/immich-backup.sh +++ b/immich/immich-backup.sh @@ -2,49 +2,31 @@ SCRIPT_ABS_LOCATION=$(realpath "$(dirname "${0}")") # shellcheck disable=SC1090 -source "$SCRIPT_ABS_LOCATION/immich-backup.env" - +source "$SCRIPT_ABS_LOCATION/../common-backup.sh" # shellcheck disable=SC1090 -source "$SCRIPT_ABS_LOCATION/../logger.sh" - -# Container Names -DB_CONTAINER="immich_postgres" -BACKUP_CONTAINER="duplicati" +source "$SCRIPT_ABS_LOCATION/immich-backup.env" # shellcheck disable=SC2034 LOG_FILE="$SCRIPT_ABS_LOCATION/immich-backup.log" -# Database Settings -DB_USER="postgres" +dump_postgres_db "$DB_CONTAINER" "$DB_USER" "/var/lib/postgresql/data/$DB_TMP_BAK_NAME" -SOURCE_DIR="/mnt/data/immich" - -# Dump Database -log "Dumping immich postgresql database..." -DB_TMP_BAK_NAME="postgres_$(date +"%Y%m%d").bak" -docker exec -t "$DB_CONTAINER" pg_dumpall \ - --clean \ - --if-exists \ - --username="$DB_USER" \ - --file="/var/lib/postgresql/data/$DB_TMP_BAK_NAME" || { log "Error: Failed to dump the immich database."; exit 1; } - -# Backup all files to target destination -log "Backing up immich files and database..." -docker exec "$BACKUP_CONTAINER" duplicati-cli backup "ssh://$BACKUP_DESTINATION" \ +run_duplicati_backup \ + "$BACKUP_DESTINATION" \ + "$APP_CONTAINER" \ + 7 \ + "$SFTP_USERNAME" \ + "$SFTP_PASSWORD" \ + "$SFTP_FINGERPRINT" \ + "$BACKUP_ENCR_PASSPHRASE" \ "$SOURCE_DIR/data/library" \ "$SOURCE_DIR/data/upload" \ "$SOURCE_DIR/data/profile" \ - "$SOURCE_DIR/postgres/$DB_TMP_BAK_NAME" \ - --backup-name="immich backup" \ - --keep-versions=7 \ - --auth-username="$SFTP_USERNAME" \ - --auth-password="$SFTP_PASSWORD" \ - --passphrase="$BACKUP_ENCR_PASSPHRASE" \ - --ssh-fingerprint="$SFTP_FINGERPRINT" \ - --prefix="immich" || { log "Error: Failed to backup immich files and database."; exit 1; } + "$SOURCE_DIR/postgres/$DB_TMP_BAK_NAME" -# Delete temporary backup files -log "Deleting temporary backup files..." -docker exec "$DB_CONTAINER" rm "/var/lib/postgresql/data/$DB_TMP_BAK_NAME" || { log "Error: Failed to delete temporary backup files."; exit 1; } +log "Deleting immich temp DB backup..." +docker exec "$DB_CONTAINER" rm "/var/lib/postgresql/data/$DB_TMP_BAK_NAME" || { + log "Error: Failed to delete temp DB backup." + exit 1 +} -log "immich backup completed successfully." diff --git a/logger.sh b/logger.sh index d494d4a..fa65f32 100755 --- a/logger.sh +++ b/logger.sh @@ -1,7 +1,6 @@ #!/bin/bash -# Function to log messages log() { - local message="$1" - echo "$(date '+%Y-%m-%d %H:%M:%S') - $message" | tee -a "$LOG_FILE" + local message="$1" + echo "$(date '+%Y-%m-%d %H:%M:%S') - $message" | tee -a "$LOG_FILE" } diff --git a/nextcloud/nextcloud-backup.sh b/nextcloud/nextcloud-backup.sh index da69855..0c20f0d 100755 --- a/nextcloud/nextcloud-backup.sh +++ b/nextcloud/nextcloud-backup.sh @@ -2,61 +2,36 @@ SCRIPT_ABS_LOCATION=$(realpath "$(dirname "${0}")") # shellcheck disable=SC1090 -source "$SCRIPT_ABS_LOCATION/nextcloud-backup.env" - +source "$SCRIPT_ABS_LOCATION/../common-backup.sh" # shellcheck disable=SC1090 -source "$SCRIPT_ABS_LOCATION/../logger.sh" - -# Container Names -APP_CONTAINER="nextcloud-app" -DB_CONTAINER="nextcloud-db" -BACKUP_CONTAINER="duplicati" +source "$SCRIPT_ABS_LOCATION/nextcloud-backup.env" # shellcheck disable=SC2034 LOG_FILE="$SCRIPT_ABS_LOCATION/nextcloud-backup.log" -# Database Settings -DB_USER="nextcloud" +enable_maintenance_mode "$APP_CONTAINER" "php occ maintenance:mode --on" -SOURCE_DIR="/mnt/data/nextcloud" +dump_mariadb_db "$DB_CONTAINER" "$DB_USER" "$DB_PASSWORD" "nextcloud" "$SOURCE_DIR/$DB_TMP_BAK_NAME" -# Put Nextcloud in Maintenance Mode -log "Putting Nextcloud in maintenance mode..." -docker exec -u www-data "$APP_CONTAINER" php occ maintenance:mode --on || { log "Error: Failed to put Nextcloud in maintenance mode."; exit 1; } +# Cant use $APP_CONTAINER as second parameter here as it contains a hyphen +run_duplicati_backup \ + "$BACKUP_DESTINATION" \ + "nextcloud" \ + 7 \ + "$SFTP_USERNAME" \ + "$SFTP_PASSWORD" \ + "$SFTP_FINGERPRINT" \ + "$BACKUP_ENCR_PASSPHRASE" \ + "$SOURCE_DIR/html/data" \ + "$SOURCE_DIR/html/config" \ + "$SOURCE_DIR/html/themes" \ + "$SOURCE_DIR/$DB_TMP_BAK_NAME" -# Dump Database -log "Dumping Nextcloud database..." -DB_TMP_BAK_NAME="nextcloud-db_$(date +"%Y%m%d").bak" -docker exec "$DB_CONTAINER" /usr/bin/mariadb-dump \ - --single-transaction \ - -h localhost \ - -u "$DB_USER" \ - -p"$DB_PASSWORD" \ - nextcloud > "$SOURCE_DIR/$DB_TMP_BAK_NAME" || { log "Error: Failed to dump the Nextcloud database."; exit 1; } +disable_maintenance_mode "$APP_CONTAINER" "php occ maintenance:mode --off" -# Backup all files to target destination -log "Backing up Nextcloud files and database..." -docker exec "$BACKUP_CONTAINER" \ - duplicati-cli backup \ - "ssh://$BACKUP_DESTINATION" \ - "$SOURCE_DIR/html/data" \ - "$SOURCE_DIR/html/config" \ - "$SOURCE_DIR/html/themes" \ - "$SOURCE_DIR/$DB_TMP_BAK_NAME" \ - --backup-name="nextcloud backup" \ - --keep-versions=7 \ - --auth-username="$SFTP_USERNAME" \ - --auth-password="$SFTP_PASSWORD" \ - --passphrase="$BACKUP_ENCR_PASSPHRASE" \ - --ssh-fingerprint="$SFTP_FINGERPRINT" \ - --prefix="nextcloud" || { log "Error: Failed to backup Nextcloud files and database."; exit 1; } +log "Deleting Nextcloud temp DB backup..." +rm "$SOURCE_DIR/$DB_TMP_BAK_NAME" || { + log "Error: Failed to delete temp DB backup." + exit 1 +} -# Turn off Maintenance Mode -log "Turning off Nextcloud maintenance mode..." -docker exec -u www-data "$APP_CONTAINER" php occ maintenance:mode --off || { log "Error: Failed to turn off Nextcloud maintenance mode."; exit 1; } - -# Delete temporary backup files -log "Deleting temporary backup files..." -rm "$SOURCE_DIR/$DB_TMP_BAK_NAME" || { log "Error: Failed to delete temporary databse file"; exit 1; } - -log "Nextcloud backup completed successfully." diff --git a/portainer/portainer-backup.sh b/portainer/portainer-backup.sh index 701c0b8..9f79e1f 100755 --- a/portainer/portainer-backup.sh +++ b/portainer/portainer-backup.sh @@ -2,40 +2,24 @@ SCRIPT_ABS_LOCATION=$(realpath "$(dirname "${0}")") # shellcheck disable=SC1090 -source "$SCRIPT_ABS_LOCATION/portainer-backup.env" - +source "$SCRIPT_ABS_LOCATION/../common-backup.sh" # shellcheck disable=SC1090 -source "$SCRIPT_ABS_LOCATION/../logger.sh" - -# Container Names -APP_CONTAINER="portainer" -BACKUP_CONTAINER="duplicati" +source "$SCRIPT_ABS_LOCATION/portainer-backup.env" # shellcheck disable=SC2034 LOG_FILE="$SCRIPT_ABS_LOCATION/portainer-backup.log" -SOURCE_DIR="/volumes/portainer" +stop_container "$APP_CONTAINER" -# Stop portainer container -log "Stopping portainer container..." -docker stop $APP_CONTAINER || { log "Error: Failed to stop portainer."; exit 1; } +run_duplicati_backup \ + "$BACKUP_DESTINATION" \ + "$APP_CONTAINER" \ + 7 \ + "$SFTP_USERNAME" \ + "$SFTP_PASSWORD" \ + "$SFTP_FINGERPRINT" \ + "$BACKUP_ENCR_PASSPHRASE" \ + "$SOURCE_DIR" -# Backup all files to target destination -log "Backing up portainer files (including the SQLite database)..." -docker exec "$BACKUP_CONTAINER" \ - duplicati-cli backup \ - "ssh://$BACKUP_DESTINATION" \ - "$SOURCE_DIR" \ - --backup-name="portainer backup" \ - --keep-versions=7 \ - --auth-username="$SFTP_USERNAME" \ - --auth-password="$SFTP_PASSWORD" \ - --passphrase="$BACKUP_ENCR_PASSPHRASE" \ - --ssh-fingerprint="$SFTP_FINGERPRINT" \ - --prefix="portainer" || { log "Error: Failed to backup portainer files and database."; exit 1; } +start_container "$APP_CONTAINER" -# Turn off Maintenance Mode -log "Starting portainer container..." -docker start "$APP_CONTAINER" || { log "Error: Failed to start portainer container."; exit 1; } - -log "portainer backup completed successfully." diff --git a/vaultwarden/vaultwarden-backup.sh b/vaultwarden/vaultwarden-backup.sh index 9c7e2e3..87ba618 100755 --- a/vaultwarden/vaultwarden-backup.sh +++ b/vaultwarden/vaultwarden-backup.sh @@ -2,39 +2,28 @@ SCRIPT_ABS_LOCATION=$(realpath "$(dirname "${0}")") # shellcheck disable=SC1090 -source "$SCRIPT_ABS_LOCATION/vaultwarden-backup.env" - +source "$SCRIPT_ABS_LOCATION/../common-backup.sh" # shellcheck disable=SC1090 -source "$SCRIPT_ABS_LOCATION/../logger.sh" - -# Container Names -BACKUP_CONTAINER="duplicati" +source "$SCRIPT_ABS_LOCATION/vaultwarden-backup.env" # shellcheck disable=SC2034 LOG_FILE="$SCRIPT_ABS_LOCATION/vaultwarden-backup.log" -SOURCE_DIR="/mnt/data/vaultwarden" +dump_sqlite_db "$SOURCE_DIR/db.sqlite3" "$SOURCE_DIR/$DB_TMP_BAK_NAME" -# Dump Database -log "Dumping vaultwarden database..." -DB_TMP_BAK_NAME=vaultwarden-db_$(date +"%Y%m%d").sqlite3 -sqlite3 "$SOURCE_DIR/db.sqlite3" ".backup $SOURCE_DIR/$DB_TMP_BAK_NAME" || { log "Error: Failed to dump the Nextcloud database."; exit 1; } +run_duplicati_backup \ + "$BACKUP_DESTINATION" \ + "vaultwarden" \ + 7 \ + "$SFTP_USERNAME" \ + "$SFTP_PASSWORD" \ + "$SFTP_FINGERPRINT" \ + "$BACKUP_ENCR_PASSPHRASE" \ + "$SOURCE_DIR" -# Backup all files to target destination -log "Backing up vaultwarden files and database..." -docker exec "$BACKUP_CONTAINER" duplicati-cli backup \ - "ssh://$BACKUP_DESTINATION" \ - "$SOURCE_DIR" \ - --backup-name="vaultwarden backup" \ - --keep-versions=7 \ - --auth-username="$SFTP_USERNAME" \ - --auth-password="$SFTP_PASSWORD" \ - --passphrase="$BACKUP_ENCR_PASSPHRASE" \ - --ssh-fingerprint="$SFTP_FINGERPRINT" \ - --prefix="vaultwarden" || { log "Error: Failed to backup vaultwarden files and database."; exit 1; } +log "Deleting vaultwarden temp DB backup..." +rm "$SOURCE_DIR/$DB_TMP_BAK_NAME" || { + log "Error: Failed to delete temp DB backup." + exit 1 +} -# Delete temporary backup files -log "Deleting temporary backup files..." -rm "$SOURCE_DIR/$DB_TMP_BAK_NAME" || { log "Error: Failed to delete temporary backup files."; exit 1; } - -log "vaultwarden backup completed successfully."