#!/bin/bash
# ==============================================================================
# Weekly LAMP Backup Script
# ==============================================================================
# #### Configuration Variables ####
SERVER_NAME="MyServer2026"
PERIOD_TYPE="Weekly"
# %V gives the ISO week number (01-53), resetting each year
PERIOD_COUNTER=$(date +%V)
BUNDLE_NAME="${SERVER_NAME}_${PERIOD_TYPE}-${PERIOD_COUNTER}.tar.gz"
STAGING_DIR="/home/somedirectory/backups"
LOG_FILE="/home/somedirectory/scripts/BackupSync-$(date +%Y).log"
# User Provided Lists
WEB_ROOT="/var/www/html"
WEB_DIRS_FILE="/home/somedirectory/scripts/web_dirs.txt"
DATABASES_FILE="/home/somedirectory/scripts/databases.txt"
mapfile -t WEB_DIRS < <(grep -vE '^\s*#|^\s*$' "$WEB_DIRS_FILE")
mapfile -t DATABASES < <(grep -vE '^\s*#|^\s*$' "$DATABASES_FILE")
# Database Credentials
MYSQL_USER="dbBackup"
MYSQL_PASS_FILE="/home/somedirectory/.backupCredsMySQL"
# QNAP NAS Configuration
QNAP_IP="192.168.123.123"
QNAP_USER="BackupUser"
QNAP_PASS_FILE="/home/somedirectory/.qnapUpload"
QNAP_DEST_DIR="/share/Public/WebserverBackups/MyServer2026/Weekly" # Adjust to your actual QNAP share path
# #### Functions ####
log_event() {
# Standard log format: YYYY-MM-DD HH:MM:SS - Message
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}
# #### Pre-flight Checks ####
# 1. Staging Directory Check
if [ ! -d "$STAGING_DIR" ]; then
mkdir -p "$STAGING_DIR"
fi
if [ ! -w "$STAGING_DIR" ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') - CRITICAL: Staging directory $STAGING_DIR is unavailable or not writable! Exiting."
exit 1
fi
# 2. QNAP Password File Check
if [ ! -f "$QNAP_PASS_FILE" ]; then
log_event "CRITICAL: sshpass file $QNAP_PASS_FILE not found! Exiting."
exit 1
fi
# 3. MySQL Password File Check
if [ ! -f "$MYSQL_PASS_FILE" ]; then
log_event "CRITICAL: MySQL password file $MYSQL_PASS_FILE not found! Exiting."
exit 1
fi
# 4. List Files Check
if [ ! -f "$WEB_DIRS_FILE" ]; then
log_event "CRITICAL: Web directory list file $WEB_DIRS_FILE not found! Exiting."
exit 1
fi
if [ ! -f "$DATABASES_FILE" ]; then
log_event "CRITICAL: Database list file $DATABASES_FILE not found! Exiting."
exit 1
fi
log_event "=== Starting $PERIOD_TYPE Backup sequence ==="
# #### 1. MySQL Database Exports ####
log_event "Starting MySQL exports..."
for db in "${DATABASES[@]}"; do
log_event "Exporting database: $db"
if mysqldump -u "$MYSQL_USER" -p"$(cat "$MYSQL_PASS_FILE")" "$db" > "$STAGING_DIR/${db}.sql"; then
log_event "Successfully exported $db"
else
log_event "ERROR: Failed to export $db"
fi
done
# #### 2. Web Directories Archiving ####
log_event "Starting Web Directory compression..."
for dir in "${WEB_DIRS[@]}"; do
if [ -d "$WEB_ROOT/$dir" ]; then
log_event "Compressing directory: $dir"
# Added _web suffix to distinguish intermediate archives from the master bundle
if tar -czf "$STAGING_DIR/${dir}_web.tar.gz" -C "$WEB_ROOT" "$dir"; then
log_event "Successfully compressed $dir"
else
log_event "ERROR: Failed to compress $dir."
fi
else
log_event "WARNING: Directory $WEB_ROOT/$dir does not exist. Skipping."
fi
done
# #### 3. Final Bundling ####
log_event "Bundling files into $BUNDLE_NAME..."
cd "$STAGING_DIR" || exit 1
# Exclude the destination bundle and specifically target intermediate files
if tar --exclude="$BUNDLE_NAME" -czf "$BUNDLE_NAME" *.sql *_web.tar.gz; then
log_event "Successfully created master bundle: $BUNDLE_NAME."
# Clean up intermediate files
rm -f *.sql *_web.tar.gz
else
log_event "CRITICAL: Failed to create master bundle! Exiting."
exit 1
fi
# #### 4. Rsync to QNAP ####
log_event "Initiating rsync transfer to QNAP NAS ($QNAP_IP)..."
if sshpass -f "$QNAP_PASS_FILE" rsync -avz -e "ssh -o StrictHostKeyChecking=no" "$STAGING_DIR/$BUNDLE_NAME" "${QNAP_USER}@${QNAP_IP}:${QNAP_DEST_DIR}/"; then
log_event "SUCCESS: Transfer of $BUNDLE_NAME to QNAP completed."
# #### 5. Cleanup ####
log_event "Performing local cleanup..."
rm -f "$STAGING_DIR/$BUNDLE_NAME"
log_event "Removed local copy of $BUNDLE_NAME to conserve disk space."
else
log_event "ERROR: Rsync transfer failed! Leaving $BUNDLE_NAME in staging area for manual review."
fi
log_event "=== $PERIOD_TYPE Backup sequence finished ==="