From f7c225f8f51193e9633e58c20585baf2992c1571 Mon Sep 17 00:00:00 2001 From: SamoilenkoVadym Date: Fri, 7 Nov 2025 14:38:12 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=20=D1=81=D0=BA=D1=80=D0=B8=D0=BF=D1=82=20?= =?UTF-8?q?=D0=B1=D1=8D=D0=BA=D0=B0=D0=BF=D0=BE=D0=B2=20backup-full-enhanc?= =?UTF-8?q?ed.sh?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Исправлены 3 критические проблемы в скрипте бэкапов: 1. backup_docker_configs: Исправлена команда tar - Удалена неверная опция -path - Использован find с передачей в tar через -T 2. backup_application_data: Добавлена проверка существования директорий - Теперь проверяет наличие директорий перед бэкапом - Пропускает несуществующие директории с предупреждением - Добавлена директория /opt/02-core/presenton/app_data 3. backup_with_restic: Исправлена логика проверки успешности - Создание файла .restic-exclude если не существует - Правильная обработка вывода restic - Улучшена проверка exit code и snapshot saved Результаты: - ✅ 4 PostgreSQL базы данных - ✅ Vault data - ✅ Docker configs - ✅ Application data - ✅ Restic backup в Cloudflare R2 - Total: 8/8 успешных компонентов (было 5/8) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../scripts/backup-full-enhanced.sh | 116 +++++++++++++----- 1 file changed, 84 insertions(+), 32 deletions(-) diff --git a/opt/05-backups/scripts/backup-full-enhanced.sh b/opt/05-backups/scripts/backup-full-enhanced.sh index 5dea6e3..a093bca 100755 --- a/opt/05-backups/scripts/backup-full-enhanced.sh +++ b/opt/05-backups/scripts/backup-full-enhanced.sh @@ -290,14 +290,15 @@ backup_vault() { backup_docker_configs() { log "[CONFIG] Backing up Docker Compose files..." local backup_file="$LOCAL_BACKUP_DIR/docker-configs-$(date +%Y%m%d-%H%M%S).tar.gz" - - if tar czf "$backup_file" -C /opt . -path "*docker-compose.yml" 2>/dev/null; then + + # Find all docker-compose.yml files and create archive + if find /opt -maxdepth 4 -name "docker-compose.yml" -o -name ".env" 2>/dev/null | tar czf "$backup_file" -T - 2>/dev/null; then local size=$(du -h "$backup_file" | cut -f1) success "Docker configs backed up ($size)" - + # Keep only last 30 days find "$LOCAL_BACKUP_DIR" -name "docker-configs-*.tar.gz" -mtime +30 -delete - + return 0 else error "Failed to backup Docker configs" @@ -308,19 +309,36 @@ backup_docker_configs() { backup_application_data() { log "[DATA] Backing up Application Data..." local backup_file="$LOCAL_BACKUP_DIR/app-data-$(date +%Y%m%d-%H%M%S).tar.gz" - - local data_dirs=( + + # Build array of existing directories only + local data_dirs=() + local candidate_dirs=( "/opt/03-business/mautic/sync_v2" "/opt/02-core/supabase/supabase/docker/volumes" + "/opt/02-core/presenton/app_data" ) - + + for dir in "${candidate_dirs[@]}"; do + if [[ -d "$dir" ]]; then + data_dirs+=("$dir") + log " Adding: $dir" + else + warning " Skipping (not found): $dir" + fi + done + + if [[ ${#data_dirs[@]} -eq 0 ]]; then + warning "No application data directories found to backup" + return 1 + fi + if tar czf "$backup_file" "${data_dirs[@]}" 2>/dev/null; then local size=$(du -h "$backup_file" | cut -f1) success "Application data backed up ($size)" - + # Keep only last 14 days find "$LOCAL_BACKUP_DIR" -name "app-data-*.tar.gz" -mtime +14 -delete - + return 0 else error "Failed to backup application data" @@ -330,28 +348,49 @@ backup_application_data() { backup_with_restic() { log "=== Uploading to Restic (Cloudflare R2) ===" - + if ! command -v restic &>/dev/null; then warning "Restic not installed, skipping cloud backup" return 1 fi - + # Initialize Restic repository if needed if ! restic cat config &>/dev/null; then log "Initializing Restic repository..." restic init || warning "Restic repository might already exist" fi - + + # Create default exclude file if it doesn't exist + local exclude_file="$BACKUP_BASE/.restic-exclude" + if [[ ! -f "$exclude_file" ]]; then + cat > "$exclude_file" << 'EOF' +*.tmp +*.log +lost+found/ +.DS_Store +EOF + fi + # Backup local directory to Restic - if restic backup "$BACKUP_BASE" --exclude-file="$BACKUP_BASE/.restic-exclude" 2>/dev/null; then - success "Restic backup completed" - - # Cleanup old snapshots (keep last 30) - restic forget --keep-daily 3 --keep-weekly 1 --prune 2>/dev/null || true - + local restic_output=$(restic backup "$BACKUP_BASE" --exclude-file="$exclude_file" 2>&1) + local restic_exit=$? + + # Log the output + echo "$restic_output" | tee -a "$LOG_FILE" > /dev/null + + # Check if backup was successful + if [[ $restic_exit -eq 0 ]] && echo "$restic_output" | grep -q "snapshot.*saved"; then + local snapshot_id=$(echo "$restic_output" | grep "snapshot" | grep "saved" | awk '{print $2}') + success "Restic backup completed (snapshot: $snapshot_id)" + + # Cleanup old snapshots + log "Cleaning up old snapshots..." + restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 3 --prune 2>/dev/null || true + return 0 else - error "Restic backup failed" + error "Restic backup failed (exit code: $restic_exit)" + echo "$restic_output" | tail -10 return 1 fi } @@ -399,18 +438,31 @@ main() { local db_user="aimpress_admin" [[ "$db_container" == "authentik-postgres" ]] && db_user="authentik" [[ "$db_container" == "postiz-postgres" ]] && db_user="postiz" + [[ "$db_container" == "supabase-db" ]] && db_user="supabase_admin" - backup_postgresql "$db_container" "$db_user" && ((successful++)) || ((failed++)) + if backup_postgresql "$db_container" "$db_user"; then + ((++successful)) + else + ((++failed)) + fi ;; mariadb) - backup_mariadb "$db_container" && ((successful++)) || ((failed++)) + if backup_mariadb "$db_container"; then + ((++successful)) + else + ((++failed)) + fi ;; mongodb) - backup_mongodb "$db_container" && ((successful++)) || ((failed++)) + if backup_mongodb "$db_container"; then + ((++successful)) + else + ((++failed)) + fi ;; *) warning "Unknown database type: $db_type" - ((failed++)) + ((++failed)) ;; esac done @@ -418,19 +470,19 @@ main() { log "" log "=== PHASE 2: Configuration Backups ===" - - backup_vault && ((successful++)) || ((failed++)) - backup_docker_configs && ((successful++)) || ((failed++)) - + + if backup_vault; then ((++successful)); else ((++failed)); fi + if backup_docker_configs; then ((++successful)); else ((++failed)); fi + log "" log "=== PHASE 3: Application Data ===" - - backup_application_data && ((successful++)) || ((failed++)) - + + if backup_application_data; then ((++successful)); else ((++failed)); fi + log "" log "=== PHASE 4: Cloud Backup (Restic) ===" - - backup_with_restic && ((successful++)) || ((failed++)) + + if backup_with_restic; then ((++successful)); else ((++failed)); fi # Calculate duration local end_time=$(date +%s)