188 lines
5.7 KiB
Bash
188 lines
5.7 KiB
Bash
#!/bin/bash
|
|
|
|
# Enable error handling
|
|
set -e
|
|
|
|
# Define log file path
|
|
LOG_DIR="/home/jelastic/mb-backups/logs"
|
|
mkdir -p "$LOG_DIR"
|
|
|
|
# Properly escape the trap command
|
|
trap 'echo "[$(date +'\''%Y-%m-%d %H:%M:%S'\'')] Backup failed" >> "$LOG_DIR/backup_error.log"' ERR
|
|
# Load the backup logic functions
|
|
source /home/jelastic/mb-backups/backup-logic.sh
|
|
|
|
# Configuration
|
|
password_file="/etc/restic-password"
|
|
APP_PATH='/var/www/webroot/ROOT'
|
|
WP_CONFIG="${APP_PATH}/wp-config.php"
|
|
backupPath='/mnt/backups'
|
|
TEMP_DIR="/tmp/wp_backup_tmp"
|
|
MAX_BACKUP_SIZE=$((10 * 1024 * 1024 * 1024)) # 10GB
|
|
|
|
# Database configuration
|
|
DB_NAME=$(grep "define( 'DB_NAME'" "$WP_CONFIG" | cut -d "'" -f 4)
|
|
DB_USER=$(grep "define( 'DB_USER'" "$WP_CONFIG" | cut -d "'" -f 4)
|
|
DB_PASSWORD=$(grep "define( 'DB_PASSWORD'" "$WP_CONFIG" | cut -d "'" -f 4)
|
|
BACKUP_USER='wp_backup'
|
|
BACKUP_PASSWORD='gaQjveXl24Xo66w'
|
|
|
|
# Ensure directories exist
|
|
mkdir -p "$LOG_DIR"
|
|
mkdir -p "$TEMP_DIR"
|
|
|
|
# Cleanup function
|
|
cleanup() {
|
|
local exit_code=$?
|
|
rm -rf "${TEMP_DIR}"/*
|
|
if [ $exit_code -ne 0 ]; then
|
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Backup failed with exit code $exit_code" | tee -a "$LOG_DIR/backup_error.log"
|
|
fi
|
|
}
|
|
trap cleanup EXIT
|
|
|
|
# Check backup size
|
|
check_backup_size() {
|
|
local path="$1"
|
|
local size=$(du -sb "$path" | cut -f1)
|
|
|
|
if [ "$size" -gt "$MAX_BACKUP_SIZE" ]; then
|
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Warning: Backup size exceeds 10GB for $path" | tee -a "$LOG_DIR/backup_warning.log"
|
|
return 1
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
# Verify backup
|
|
verify_backup() {
|
|
local tag="$1"
|
|
local latest_snapshot=$(restic snapshots --latest 1 --tag "$tag" --json | jq -r '.[0].id')
|
|
if [ -n "$latest_snapshot" ]; then
|
|
restic check --read-data "$latest_snapshot"
|
|
return $?
|
|
fi
|
|
return 1
|
|
}
|
|
|
|
# Initialize backup
|
|
if [ ! -f "$password_file" ]; then
|
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: Password file not found at $password_file" | tee -a "$LOG_DIR/backup_error.log"
|
|
exit 1
|
|
fi
|
|
|
|
export RESTIC_PASSWORD=$(cat "$password_file")
|
|
export RESTIC_REPOSITORY="$backupPath"
|
|
|
|
# Check repository
|
|
check_backup_repo() {
|
|
restic snapshots > /dev/null 2>&1
|
|
if [ $? -ne 0 ]; then
|
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: Backup repository is not accessible" | tee -a "$LOG_DIR/backup_error.log"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
check_backup_repo
|
|
|
|
# Backup functions
|
|
backup_core_files() {
|
|
local log_file="${LOG_DIR}/backup_core_files_$(date +'%Y-%m-%d').log"
|
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Starting Core Files Backup" | tee -a "$log_file"
|
|
|
|
check_backup_size "$APP_PATH" || return 1
|
|
|
|
local excludePaths=("$APP_PATH/wp-content/uploads")
|
|
local excludeOptions=""
|
|
for path in "${excludePaths[@]}"; do
|
|
excludeOptions+="--exclude $path "
|
|
done
|
|
|
|
if restic backup $excludeOptions "$APP_PATH" --tag core_files --tag full_backup; then
|
|
verify_backup "core_files" || return 1
|
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Core files backup completed successfully" | tee -a "$log_file"
|
|
return 0
|
|
fi
|
|
return 1
|
|
}
|
|
|
|
backup_media_themes() {
|
|
local log_file="${LOG_DIR}/backup_media_themes_$(date +'%Y-%m-%d').log"
|
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Starting Media and Themes Backup" | tee -a "$log_file"
|
|
|
|
local includePaths=("$APP_PATH/wp-content/uploads")
|
|
|
|
for path in "${includePaths[@]}"; do
|
|
check_backup_size "$path" || continue
|
|
|
|
if restic backup "$path" --tag media_themes --tag full_backup; then
|
|
verify_backup "media_themes" || return 1
|
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Backup completed successfully for $path" | tee -a "$log_file"
|
|
else
|
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: Backup failed for $path" | tee -a "$log_file"
|
|
return 1
|
|
fi
|
|
done
|
|
}
|
|
|
|
backup_database() {
|
|
local log_file="${LOG_DIR}/backup_database_$(date +'%Y-%m-%d').log"
|
|
local temp_dump="${TEMP_DIR}/wp_backup_${DB_NAME}_$(date +'%Y%m%d').sql"
|
|
|
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Starting Database Backup" | tee -a "$log_file"
|
|
|
|
if ! mysqldump -u "$BACKUP_USER" --password="$BACKUP_PASSWORD" "$DB_NAME" > "$temp_dump" 2>> "$log_file"; then
|
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: Database dump failed" | tee -a "$log_file"
|
|
return 1
|
|
fi
|
|
|
|
check_backup_size "$temp_dump" || return 1
|
|
|
|
if restic backup "$temp_dump" --tag wordpress_db --tag full_backup; then
|
|
verify_backup "wordpress_db" || return 1
|
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Database backup completed successfully" | tee -a "$log_file"
|
|
return 0
|
|
else
|
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: Database backup failed" | tee -a "$log_file"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
cleanup_old_backups() {
|
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Starting backup rotation" | tee -a "$LOG_DIR/backup_rotation.log"
|
|
restic forget \
|
|
--keep-daily 7 \
|
|
--keep-weekly 4 \
|
|
--keep-monthly 3 \
|
|
--prune \
|
|
--tag full_backup \
|
|
2>> "$LOG_DIR/backup_rotation.log"
|
|
}
|
|
|
|
# Main execution
|
|
main() {
|
|
local start_time=$(date +%s)
|
|
local backup_date=$(date +'%Y-%m-%d_%H-%M-%S')
|
|
local main_log="${LOG_DIR}/full_backup_${backup_date}.log"
|
|
|
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Starting full backup process" | tee -a "$main_log"
|
|
|
|
backup_core_files || exit 1
|
|
backup_media_themes || exit 1
|
|
backup_database || exit 1
|
|
|
|
cleanup_old_backups
|
|
|
|
local end_time=$(date +%s)
|
|
local duration=$((end_time - start_time))
|
|
|
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Full backup completed in $duration seconds" | tee -a "$main_log"
|
|
}
|
|
|
|
# Argument handling
|
|
if [ "$1" == "backup_now" ]; then
|
|
main
|
|
else
|
|
echo "Usage: $0 backup_now"
|
|
exit 1
|
|
fi
|