taskmanager/scripts/backup.ps1

33 lines
1.8 KiB
PowerShell

param(
[string]$Project = 'taskmanager',
[string]$EnvFile = '.env',
[switch]$Demo
)
$ErrorActionPreference = 'Stop'
Set-Location (Split-Path $PSScriptRoot -Parent)
$env:TASKMANAGER_ENV_FILE = $EnvFile
$compose = @('compose','--project-name',$Project,'--env-file',$EnvFile,'-f','docker-compose.yml')
if ($Demo) { $compose += @('-f','docker-compose.demo.yml') }
function Invoke-Compose {
& docker @compose @args
if ($LASTEXITCODE -ne 0) { throw 'Docker Compose command failed' }
}
$running = @(Invoke-Compose ps --status running --services)
$restart = @($running | Where-Object { $_ -in @('app','worker') })
$destination = Join-Path (Get-Location) ('backups/' + (Get-Date -Format 'yyyyMMdd-HHmmss') + '-' + [guid]::NewGuid().ToString('N').Substring(0,8))
New-Item -ItemType Directory -Path $destination | Out-Null
try {
if ($restart.Count) { Invoke-Compose stop -t 60 @restart }
Invoke-Compose exec -T db sh -c 'pg_dump -U "$POSTGRES_USER" -d "$POSTGRES_DB" -Fc -f /tmp/taskmanager-backup.dump'
$dbContainer = Invoke-Compose ps -q db
& docker cp "${dbContainer}:/tmp/taskmanager-backup.dump" (Join-Path $destination 'database.dump')
if ($LASTEXITCODE -ne 0) { throw 'Database backup copy failed' }
Invoke-Compose run --rm --no-deps -v "${destination}:/backup" worker tar -czf /backup/uploads.tar.gz -C /app/private-uploads .
Get-FileHash -Algorithm SHA256 -LiteralPath (Join-Path $destination 'database.dump'),(Join-Path $destination 'uploads.tar.gz') |
Select-Object @{Name='File';Expression={Split-Path $_.Path -Leaf}},Hash |
ConvertTo-Json | Set-Content -LiteralPath (Join-Path $destination 'checksums.json') -Encoding utf8
Write-Host "Backup: $destination"
} finally {
if ($restart.Count) { Invoke-Compose start @restart }
}