[CmdletBinding()] param( [Parameter(Mandatory = $true)][string]$LegacyWordPressContainer, [string]$LegacyDatabaseContainer, [string]$LegacyUploadsPath = '/var/www/html/wp-content/uploads', [string]$StaticUploadsTarget = 'static/wp-content/uploads', [string]$BackupRoot = 'migration-backups', [string]$MySqlDatabase, [string]$MySqlUser, [string]$MySqlPassword, [switch]$SkipUploads, [switch]$SkipDatabaseDump ) $scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path . (Join-Path $scriptDir 'common.ps1') $repoRoot = Split-Path -Parent $scriptDir $backupRootPath = Resolve-AbsolutePath -BasePath $repoRoot -Path $BackupRoot $staticUploadsPath = Resolve-AbsolutePath -BasePath $repoRoot -Path $StaticUploadsTarget $timestamp = Get-Date -Format 'yyyyMMdd-HHmmss' $runRoot = Join-Path $backupRootPath $timestamp $stagingRoot = Join-Path $runRoot 'uploads-staging' $uploadsArchivePath = Join-Path $runRoot 'uploads' $sqlDumpPath = Join-Path $runRoot 'wordpress.sql' Write-Step 'Preparing WordPress migration workspace' Assert-Command docker New-Item -ItemType Directory -Force -Path $runRoot | Out-Null if (-not $SkipDatabaseDump) { if (-not $LegacyDatabaseContainer) { throw 'LegacyDatabaseContainer is required unless -SkipDatabaseDump is used.' } if (-not $MySqlDatabase -or -not $MySqlUser -or -not $MySqlPassword) { throw 'MySqlDatabase, MySqlUser, and MySqlPassword are required unless -SkipDatabaseDump is used.' } Write-Step 'Dumping the legacy WordPress database' $dumpCommand = "exec mysqldump --single-transaction --quick --lock-tables=false -u$MySqlUser -p`"$MySqlPassword`" $MySqlDatabase" $dumpOutput = & docker exec $LegacyDatabaseContainer sh -lc $dumpCommand if ($LASTEXITCODE -ne 0) { throw 'mysqldump failed.' } [System.IO.File]::WriteAllText($sqlDumpPath, ($dumpOutput -join [Environment]::NewLine)) Write-Note "Database dump saved to $sqlDumpPath" } if (-not $SkipUploads) { Write-Step 'Copying wp-content/uploads from the legacy WordPress container' New-Item -ItemType Directory -Force -Path $stagingRoot | Out-Null $sourceSpec = '{0}:{1}' -f $LegacyWordPressContainer, $LegacyUploadsPath Invoke-Checked -FilePath 'docker' -Arguments @('cp', $sourceSpec, $stagingRoot) $copiedUploads = Join-Path $stagingRoot 'uploads' if (-not (Test-Path $copiedUploads)) { throw "Expected copied uploads at $copiedUploads but it was not found." } New-Item -ItemType Directory -Force -Path (Split-Path -Parent $staticUploadsPath) | Out-Null if (Test-Path $staticUploadsPath) { Remove-Item -LiteralPath $staticUploadsPath -Recurse -Force } Move-Item -LiteralPath $copiedUploads -Destination $uploadsArchivePath Copy-Item -LiteralPath $uploadsArchivePath -Destination $staticUploadsPath -Recurse -Force Write-Note "Uploads copied into $staticUploadsPath" Write-Note "Archive copy saved to $uploadsArchivePath" } Write-Step 'Migration artifacts prepared' Write-Host "Backup folder: $runRoot"