# Script to backup the entire Postgres Docker volume $timestamp = Get-Date -Format "yyyy-MM-dd_HH-mm-ss" $scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path $backupDir = Join-Path $scriptDir "backups" $volumeName = "gitea-docker_postgres-data" $backupFile = "postgres-volume-backup-$timestamp.tar" $backupFilePath = Join-Path $backupDir $backupFile $redundantBackupDir = "D:\Pr00jects\gitea-docker" $logFile = Join-Path $backupDir "volume-backup-log.txt" $currentDir = Get-Location # Ensure backup directory exists if (-not (Test-Path $backupDir)) { New-Item -ItemType Directory -Path $backupDir } # Ensure redundant backup directory exists if (-not (Test-Path $redundantBackupDir)) { try { New-Item -ItemType Directory -Path $redundantBackupDir -Force } catch { Add-Content -Path $logFile -Value "[$timestamp] Warning: Could not create redundant backup directory at $redundantBackupDir. Error: $_" } } # Log start of backup Add-Content -Path $logFile -Value "[$timestamp] Starting volume backup for $volumeName..." # Check if volume exists $volumeExists = docker volume ls --format "{{.Name}}" | Select-String -Pattern "^$volumeName$" if (-not $volumeExists) { Write-Host "Volume $volumeName not found!" -ForegroundColor Red Add-Content -Path $logFile -Value "[$timestamp] Error: Volume $volumeName not found!" exit 1 } # Create a temporary container to access the volume Write-Host "Creating backup of Docker volume $volumeName..." Add-Content -Path $logFile -Value "[$timestamp] Creating backup to $backupFilePath..." # Change to backup directory and use simple relative paths for Docker Set-Location -Path $backupDir docker run --rm -v ${volumeName}:/volume -v ${PWD}:/backup alpine tar -cf /backup/$backupFile -C /volume ./ # Restore original directory Set-Location -Path $currentDir # Check if backup was successful if ($LASTEXITCODE -eq 0 -and (Test-Path $backupFilePath) -and (Get-Item $backupFilePath).Length -gt 0) { Write-Host "Volume backup completed successfully to $backupFilePath!" -ForegroundColor Green Add-Content -Path $logFile -Value "[$timestamp] Volume backup completed successfully!" # Optional: Compress the backup file Write-Host "Compressing backup file..." Add-Content -Path $logFile -Value "[$timestamp] Compressing backup file..." $zipFileName = "$backupFilePath.zip" Compress-Archive -Path $backupFilePath -DestinationPath $zipFileName -Force Remove-Item $backupFilePath Write-Host "Backup compressed to $zipFileName" -ForegroundColor Green Add-Content -Path $logFile -Value "[$timestamp] Backup compressed to $zipFileName" # Copy backup to redundant location if (Test-Path $redundantBackupDir) { try { $redundantBackupFile = Join-Path $redundantBackupDir (Split-Path -Leaf $zipFileName) Copy-Item -Path $zipFileName -Destination $redundantBackupFile -Force Write-Host "Backup copied to redundant location: $redundantBackupFile" -ForegroundColor Green Add-Content -Path $logFile -Value "[$timestamp] Backup copied to redundant location: $redundantBackupFile" } catch { Write-Host "Error copying backup to redundant location: $_" -ForegroundColor Red Add-Content -Path $logFile -Value "[$timestamp] Error copying backup to redundant location: $_" } } else { Write-Host "Warning: Redundant backup directory not found: $redundantBackupDir" -ForegroundColor Yellow Add-Content -Path $logFile -Value "[$timestamp] Warning: Redundant backup directory not found: $redundantBackupDir" } } else { Write-Host "Volume backup failed!" -ForegroundColor Red Add-Content -Path $logFile -Value "[$timestamp] Volume backup failed!" } # Optional: Clean up old volume backups (keep last 5) $oldBackups = Get-ChildItem -Path $backupDir -Filter "postgres-volume-backup-*.zip" | Sort-Object LastWriteTime -Descending | Select-Object -Skip 5 foreach ($backup in $oldBackups) { Remove-Item $backup.FullName Write-Host "Removed old volume backup: $($backup.Name)" Add-Content -Path $logFile -Value "[$timestamp] Removed old volume backup: $($backup.Name)" }