MilliSim/backend/deploy-to-iis.ps1

179 lines
8.4 KiB
PowerShell
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ============================================================================
# MilliSim 后端部署脚本IIS 独立后端 + 反向代理架构)
# 在部署服务器上以管理员身份运行 PowerShell 执行此脚本
# 用法:.\deploy-to-iis.ps1 -DeployDir "C:\MilliSim\Backend" -ZipPath "C:\Deploy\MilliSim.Api.publish.clean.zip"
# ============================================================================
param(
[Parameter(Mandatory=$true)]
[string]$DeployDir,
[Parameter(Mandatory=$true)]
[string]$ZipPath,
[string]$ServiceName = "MilliSimApi"
)
$ErrorActionPreference = "Stop"
Write-Host "================================================" -ForegroundColor Cyan
Write-Host " MilliSim 后端部署脚本" -ForegroundColor Cyan
Write-Host "================================================" -ForegroundColor Cyan
Write-Host "部署目录: $DeployDir"
Write-Host "发布包: $ZipPath"
Write-Host "服务名: $ServiceName"
Write-Host ""
# 1. 前置检查
Write-Host "[1/7] 前置检查..." -ForegroundColor Yellow
if (-not (Test-Path $ZipPath)) { throw "发布包不存在: $ZipPath" }
if (-not (Test-Path $DeployDir)) { throw "部署目录不存在: $DeployDir" }
if (-not (Test-Path "$DeployDir\MilliSim.Api.dll")) { throw "部署目录下未找到 MilliSim.Api.dll确认是否正确的部署目录" }
Write-Host " [OK] 检查通过" -ForegroundColor Green
# 2. 备份当前部署目录
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
$backupDir = "$DeployDir.bak_$timestamp"
Write-Host "[2/7] 备份当前部署目录到: $backupDir" -ForegroundColor Yellow
Copy-Item -Path $DeployDir -Destination $backupDir -Recurse -Force
Write-Host " [OK] 备份完成" -ForegroundColor Green
# 3. 停止后端服务
Write-Host "[3/7] 停止后端服务..." -ForegroundColor Yellow
$serviceStopped = $false
try {
$svc = Get-Service -Name $ServiceName -ErrorAction Stop
if ($svc.Status -eq "Running") {
Stop-Service -Name $ServiceName -Force
Start-Sleep -Seconds 2
Write-Host " [OK] Windows 服务 '$ServiceName' 已停止" -ForegroundColor Green
} else {
Write-Host " [SKIP] 服务已处于停止状态" -ForegroundColor Gray
}
$serviceStopped = $true
} catch {
Write-Host " [INFO] 未找到 Windows 服务 '$ServiceName',尝试查找 dotnet 进程..." -ForegroundColor Gray
$procs = Get-Process -Name "dotnet","MilliSim.Api" -ErrorAction SilentlyContinue | Where-Object { $_.Path -like "*$DeployDir*" }
if ($procs) {
$procs | Stop-Process -Force
Start-Sleep -Seconds 2
Write-Host " [OK] 已终止 dotnet 进程: $($procs.Id -join ', ')" -ForegroundColor Green
} else {
Write-Host " [INFO] 未找到运行中的后端进程" -ForegroundColor Gray
}
}
# 4. 备份当前 appsettings.json保留服务器配置
$appSettingsPath = "$DeployDir\appsettings.json"
$appSettingsBackup = "$DeployDir\appsettings.json.server_backup"
if (Test-Path $appSettingsPath) {
Copy-Item -Path $appSettingsPath -Destination $appSettingsBackup -Force
Write-Host "[4/7] 已备份服务器 appsettings.json 到: $appSettingsBackup" -ForegroundColor Green
} else {
Write-Host "[4/7] 部署目录无 appsettings.json跳过备份" -ForegroundColor Gray
}
# 5. 解压新代码(不删除 wwwroot/uploads 和 wwwroot/backups 的文件)
Write-Host "[5/7] 解压新代码到部署目录..." -ForegroundColor Yellow
Add-Type -AssemblyName System.IO.Compression.FileSystem
$zip = [System.IO.Compression.ZipFile]::OpenRead($ZipPath)
try {
foreach ($entry in $zip.Entries) {
# 跳过 wwwroot/uploads 和 wwwroot/backups 下的所有文件(保留服务器上的上传文件)
if ($entry.FullName -match "^wwwroot/uploads/" -and $entry.Length -gt 0) { continue }
if ($entry.FullName -match "^wwwroot/backups/" -and $entry.Length -gt 0) { continue }
$targetPath = Join-Path $DeployDir $entry.FullName
$targetDir = Split-Path $targetPath -Parent
if (-not (Test-Path $targetDir)) { New-Item -ItemType Directory -Path $targetDir -Force | Out-Null }
if ($entry.Length -gt 0) {
[System.IO.Compression.ZipFileExtensions]::ExtractToFile($entry, $targetPath, $true)
} elseif (-not (Test-Path $targetPath)) {
New-Item -ItemType Directory -Path $targetPath -Force | Out-Null
}
}
Write-Host " [OK] 解压完成(已保留 wwwroot/uploads 和 wwwroot/backups 中的文件)" -ForegroundColor Green
} finally {
$zip.Dispose()
}
# 6. 恢复服务器 appsettings.json如果存在备份
if (Test-Path $appSettingsBackup) {
Copy-Item -Path $appSettingsBackup -Destination $appSettingsPath -Force
Write-Host "[6/7] 已恢复服务器 appsettings.json保留端口/连接字符串配置)" -ForegroundColor Green
} else {
Write-Host "[6/7] 未恢复 appsettings.json使用发布包默认配置" -ForegroundColor Gray
}
# 7. 启动后端服务
Write-Host "[7/7] 启动后端服务..." -ForegroundColor Yellow
if ($serviceStopped) {
try {
Start-Service -Name $ServiceName -ErrorAction Stop
Start-Sleep -Seconds 3
$svc = Get-Service -Name $ServiceName
if ($svc.Status -eq "Running") {
Write-Host " [OK] Windows 服务 '$ServiceName' 已启动" -ForegroundColor Green
} else {
Write-Host " [WARN] 服务启动状态: $($svc.Status)" -ForegroundColor Yellow
}
} catch {
Write-Host " [ERROR] 服务启动失败: $_" -ForegroundColor Red
Write-Host " 请手动启动服务或检查日志" -ForegroundColor Yellow
}
} else {
Write-Host " [INFO] 之前未通过 Windows 服务停止,请用原启动方式重启后端" -ForegroundColor Gray
Write-Host " 例如: cd $DeployDir; dotnet MilliSim.Api.dll --urls http://localhost:30001" -ForegroundColor Gray
}
# 验证
Write-Host ""
Write-Host "================================================" -ForegroundColor Cyan
Write-Host " 部署完成,开始验证" -ForegroundColor Cyan
Write-Host "================================================" -ForegroundColor Cyan
Start-Sleep -Seconds 5
Write-Host "[验证 1] 检查后端端口 30001 是否监听..." -ForegroundColor Yellow
$conn = Test-NetConnection -ComputerName localhost -Port 30001 -WarningAction SilentlyContinue
if ($conn.TcpTestSucceeded) {
Write-Host " [OK] 端口 30001 监听正常" -ForegroundColor Green
} else {
Write-Host " [FAIL] 端口 30001 未监听,请检查后端启动日志" -ForegroundColor Red
}
Write-Host "[验证 2] 调用 /api/system/public-settings ..." -ForegroundColor Yellow
try {
$resp = Invoke-WebRequest -Uri "http://localhost:30001/api/system/public-settings" -UseBasicParsing -TimeoutSec 10
Write-Host " [OK] HTTP $($resp.StatusCode)" -ForegroundColor Green
} catch {
Write-Host " [FAIL] 请求失败: $_" -ForegroundColor Red
}
Write-Host "[验证 3] 检查 /uploads/ 路径是否由后端服务 ..." -ForegroundColor Yellow
try {
$resp = Invoke-WebRequest -Uri "http://localhost:30001/uploads/" -UseBasicParsing -TimeoutSec 10
Write-Host " [OK] HTTP $($resp.StatusCode)" -ForegroundColor Green
} catch {
$code = $_.Exception.Response.StatusCode.value__
if ($code -eq 404) {
Write-Host " [OK] HTTP 404目录浏览禁用符合预期" -ForegroundColor Green
} else {
Write-Host " [INFO] HTTP $code" -ForegroundColor Gray
}
}
Write-Host ""
Write-Host "================================================" -ForegroundColor Cyan
Write-Host " 部署脚本结束" -ForegroundColor Cyan
Write-Host "================================================" -ForegroundColor Cyan
Write-Host ""
Write-Host "下一步:在浏览器访问前端页面,验证以下 4 个问题是否全部解决:" -ForegroundColor White
Write-Host " 1. 员工管理页面头像加载(应返回 /uploads/avatars/xxx.png不再请求 COS"
Write-Host " 2. 轮播图列表页图片加载"
Write-Host " 3. 项目封面/视频加载"
Write-Host " 4. WebGL 资源加载(.unityweb 文件应返回 200 + application/octet-stream"
Write-Host ""
Write-Host "如需回滚:删除 $DeployDir,重命名 $backupDir$DeployDir,重启服务" -ForegroundColor Gray
Write-Host ""
Write-Host "如服务器上缺少 COS 模式时上传的旧文件,可调用迁移端点补齐:"
Write-Host " Invoke-WebRequest -Uri 'http://localhost:30001/api/system/migrate-cos-to-local' -Method POST -Headers @{Authorization='Bearer <admin token>'}"