#!/bin/bash # # Full System Backup Script using rsync # Backs up entire server to local Mac storage # # Usage: ./system-backup.sh # set -e # Exit on error # Configuration SERVER="ubuntu@51.89.231.46" BACKUP_DIR="/Volumes/SSD/Aimpress_Cloud_Prod/system-backup" LOG_FILE="$BACKUP_DIR/backup-$(date +%Y%m%d-%H%M%S).log" TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S") # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color # Functions log() { echo "[$TIMESTAMP] $1" | tee -a "$LOG_FILE" } log_success() { echo -e "${GREEN}[$TIMESTAMP] ✓ $1${NC}" | tee -a "$LOG_FILE" } log_error() { echo -e "${RED}[$TIMESTAMP] ✗ $1${NC}" | tee -a "$LOG_FILE" } log_warning() { echo -e "${YELLOW}[$TIMESTAMP] ⚠ $1${NC}" | tee -a "$LOG_FILE" } # Create backup directory if it doesn't exist mkdir -p "$BACKUP_DIR" log "=========================================" log "Starting Full System Backup" log "Server: $SERVER" log "Backup Location: $BACKUP_DIR" log "=========================================" # Check if server is reachable log "Checking server connection..." if ! ssh -o ConnectTimeout=10 "$SERVER" "echo 'Server is reachable'" > /dev/null 2>&1; then log_error "Cannot connect to server $SERVER" exit 1 fi log_success "Server is reachable" # Check available disk space log "Checking available disk space..." AVAILABLE_SPACE=$(df -h /Volumes/SSD | tail -1 | awk '{print $4}') log "Available space on Mac: $AVAILABLE_SPACE" SERVER_USAGE=$(ssh "$SERVER" "df -h / | tail -1 | awk '{print \$3}'") log "Server disk usage: $SERVER_USAGE" # Rsync options RSYNC_OPTS=( -avz # Archive mode, verbose, compress --progress # Show progress --delete # Delete files that don't exist on source --delete-excluded # Delete excluded files on destination --partial # Keep partially transferred files --partial-dir=.rsync-partial # Store partial transfers --human-readable # Human readable numbers --stats # Show transfer statistics ) # Exclude patterns EXCLUDE_PATTERNS=( # System and temporary "/proc/*" "/sys/*" "/dev/*" "/run/*" "/tmp/*" "/var/tmp/*" "/lost+found" # Swap and memory "/swapfile" "/swap.img" "*.swap" # Docker runtime (will be synced via Syncthing) "/var/lib/docker/overlay2/*" "/var/lib/docker/containers/*/logs/*" # Large cache and logs "/var/cache/*" "/var/log/*.gz" "/var/log/*.old" "*.log.1" "*.log.2" # Already synced by Syncthing "/opt/.stfolder" "/opt/.stversions" "/data/.stfolder" "/data/.stversions" "/home/ubuntu/.stfolder" "/home/ubuntu/.stversions" # Temporary build files "*.tmp" "*.temp" ".cache/*" # System sockets "*.sock" "*.socket" ) # Build exclude arguments EXCLUDE_ARGS=() for pattern in "${EXCLUDE_PATTERNS[@]}"; do EXCLUDE_ARGS+=("--exclude=$pattern") done log "Starting rsync backup..." log_warning "This may take a long time depending on server size and network speed" # Perform backup if rsync "${RSYNC_OPTS[@]}" "${EXCLUDE_ARGS[@]}" \ "$SERVER:/" \ "$BACKUP_DIR/" \ 2>&1 | tee -a "$LOG_FILE"; then log_success "Backup completed successfully!" # Calculate backup size BACKUP_SIZE=$(du -sh "$BACKUP_DIR" | cut -f1) log "Backup size: $BACKUP_SIZE" # Create backup metadata cat > "$BACKUP_DIR/.backup-metadata.txt" << EOF Backup Date: $(date) Server: $SERVER Backup Location: $BACKUP_DIR Backup Size: $BACKUP_SIZE Status: Success EOF log_success "Metadata saved to $BACKUP_DIR/.backup-metadata.txt" else log_error "Backup failed! Check log file: $LOG_FILE" exit 1 fi log "=========================================" log "Backup Summary" log "Log file: $LOG_FILE" log "Backup location: $BACKUP_DIR" log "=========================================" log_success "All done! System backup completed." # Cleanup old logs (keep last 30) log "Cleaning up old log files..." cd "$BACKUP_DIR" ls -tp backup-*.log 2>/dev/null | tail -n +31 | xargs -I {} rm -- {} 2>/dev/null || true log_success "Cleanup completed" exit 0