# ============================================ # 从标准版升级到Pro版脚本 # 支持一键升级,保留数据 # ============================================ param( [Parameter(Mandatory=$true)] [string]$Server, [string]$Username = "root", [string]$Password = "", [string]$RemotePath = "/root/deploy", [string]$DockerRegistry = "", [string]$ImageTag = "latest" ) $ErrorActionPreference = "Stop" # 颜色输出函数 function Write-Step { param([string]$Message) Write-Host "===> $Message" -ForegroundColor Cyan } function Write-Success { param([string]$Message) Write-Host "✓ $Message" -ForegroundColor Green } function Write-Error { param([string]$Message) Write-Host "✗ $Message" -ForegroundColor Red } function Write-Warning { param([string]$Message) Write-Host "⚠ $Message" -ForegroundColor Yellow } Write-Host "" Write-Host "==========================================" -ForegroundColor Cyan Write-Host "从标准版升级到Pro版" -ForegroundColor Cyan Write-Host "==========================================" -ForegroundColor Cyan Write-Host "" # 检查参数 if (-not $DockerRegistry) { Write-Error "错误: 必须提供 Docker 镜像仓库地址 (DockerRegistry)" Write-Host "" Write-Host "用法示例:" -ForegroundColor Yellow Write-Host " .\upgrade-to-pro.ps1 -Server 45.249.208.118 -DockerRegistry your-registry.com" -ForegroundColor Gray exit 1 } # SSH 连接配置 $plinkPath = "C:\Program Files\PuTTY\plink.exe" if (-not (Test-Path $plinkPath)) { Write-Error "错误: 未找到 plink.exe,请安装 PuTTY" exit 1 } # 获取密码 if (-not $Password) { $securePassword = Read-Host "请输入SSH密码" -AsSecureString $Password = [Runtime.InteropServices.Marshal]::PtrToStringAuto( [Runtime.InteropServices.Marshal]::SecureStringToBSTR($securePassword) ) } $hostKey = "SHA256:WZOtvC/+IWw29P8vyovSabmIRFkQ/Bnmhj+qhTshA4Q" # SSH 命令执行函数 function Invoke-SSHCommand { param([string]$Command) $output = & $plinkPath -batch -ssh -hostkey $hostKey -pw $Password "${Username}@${Server}" $Command 2>&1 return $output } Write-Step "检查当前版本..." $currentCompose = Invoke-SSHCommand "cd ${RemotePath} && ls -la docker-compose.yml 2>/dev/null || echo 'not-found'" if ($currentCompose -match "not-found") { Write-Error "错误: 未找到 docker-compose.yml,请确认部署路径正确" exit 1 } # 检查当前使用的配置文件 $currentConfig = Invoke-SSHCommand "cd ${RemotePath} && readlink -f docker-compose.yml 2>/dev/null || echo docker-compose.yml" Write-Host " 当前配置: $currentConfig" -ForegroundColor Gray # 检查是否已经是Pro版 if ($currentConfig -match "prod") { Write-Warning "当前已经是Pro版,无需升级" exit 0 } Write-Step "备份当前配置和数据..." $backupDir = "${RemotePath}/backup_$(Get-Date -Format 'yyyyMMdd_HHmmss')" Invoke-SSHCommand "cd ${RemotePath} && mkdir -p ${backupDir} && cp docker-compose.yml ${backupDir}/ && cp docker-compose.*.yml ${backupDir}/ 2>/dev/null || true" Write-Success "备份完成: $backupDir" Write-Step "备份数据库..." $dbBackupFile = "backup_$(Get-Date -Format 'yyyyMMdd_HHmmss').sql" Invoke-SSHCommand "cd ${RemotePath} && docker compose exec -T postgres pg_dump -U postgres youyidian3d > ${backupDir}/${dbBackupFile} 2>&1 || echo 'backup-failed'" Write-Success "数据库备份完成" Write-Step "停止当前服务..." Invoke-SSHCommand "cd ${RemotePath} && docker compose down" Write-Success "服务已停止" Write-Step "上传Pro版配置文件..." $scpPath = "C:\Program Files\PuTTY\pscp.exe" if (Test-Path $scpPath) { & $scpPath -pw $Password "docker-compose.prod.yml" "${Username}@${Server}:${RemotePath}/docker-compose.prod.yml" Write-Success "Pro版配置文件已上传" } else { Write-Warning "未找到 pscp.exe,将使用SSH直接创建配置文件" # 读取本地配置文件内容 $prodComposeContent = Get-Content "docker-compose.prod.yml" -Raw # 通过SSH创建文件 $prodComposeContent | Invoke-SSHCommand "cd ${RemotePath} && cat > docker-compose.prod.yml" Write-Success "Pro版配置文件已创建" } Write-Step "创建docker-compose.yml链接..." Invoke-SSHCommand "cd ${RemotePath} && ln -sf docker-compose.prod.yml docker-compose.yml" Write-Success "配置文件链接已创建" Write-Step "配置环境变量..." # 创建或更新 .env 文件 $envContent = @" # Docker镜像仓库 DOCKER_REGISTRY=${DockerRegistry} # 镜像标签 IMAGE_TAG=${ImageTag} # 服务器IP(如果未设置) SERVER_IP=${Server} # MinIO配置(Pro版需要) MINIO_ROOT_USER=${env:MINIO_ROOT_USER:-minioadmin} MINIO_ROOT_PASSWORD=${env:MINIO_ROOT_PASSWORD:-minioadmin123456} S3_BUCKET=${env:S3_BUCKET:-youyidian3d} "@ $envContent | Invoke-SSHCommand "cd ${RemotePath} && cat > .env.prod" Write-Success "环境变量已配置" Write-Step "拉取Pro版镜像和依赖..." # 拉取MinIO镜像(使用国内镜像源) Write-Host " 拉取MinIO镜像..." -ForegroundColor Gray Invoke-SSHCommand "docker pull minio/minio:RELEASE.2025-04-22T22-12-26Z" Invoke-SSHCommand "docker pull minio/mc:RELEASE.2025-04-22T22-12-26Z" # 拉取应用镜像 Write-Host " 拉取应用镜像..." -ForegroundColor Gray $appImage = "${DockerRegistry}/youyidian-3d-material:pro-${ImageTag}" Invoke-SSHCommand "docker pull ${appImage}" Write-Success "镜像拉取完成" Write-Step "启动Pro版服务..." Invoke-SSHCommand "cd ${RemotePath} && docker compose up -d" Write-Success "服务已启动" Write-Step "等待服务就绪..." Start-Sleep -Seconds 10 # 检查服务状态 $services = Invoke-SSHCommand "cd ${RemotePath} && docker compose ps --format json" Write-Host " 服务状态:" -ForegroundColor Gray Invoke-SSHCommand "cd ${RemotePath} && docker compose ps" Write-Step "验证升级结果..." # 检查健康状态 $healthCheck = Invoke-SSHCommand "curl -s http://localhost:4320/api/health || echo 'not-ready'" if ($healthCheck -match "not-ready") { Write-Warning "应用可能还在启动中,请稍后检查" } else { Write-Success "应用健康检查通过" } Write-Host "" Write-Host "==========================================" -ForegroundColor Cyan Write-Host "升级完成!" -ForegroundColor Green Write-Host "==========================================" -ForegroundColor Cyan Write-Host "" Write-Host "📋 升级信息:" -ForegroundColor Yellow Write-Host " 备份目录: ${backupDir}" -ForegroundColor Gray Write-Host " 应用地址: http://${Server}:4320" -ForegroundColor Gray Write-Host " MinIO控制台: http://${Server}:9001" -ForegroundColor Gray Write-Host "" Write-Host "💡 提示:" -ForegroundColor Yellow Write-Host " - 数据已自动迁移" -ForegroundColor Gray Write-Host " - 如需回滚,请查看备份目录" -ForegroundColor Gray Write-Host " - 建议测试所有功能确保正常" -ForegroundColor Gray Write-Host ""