flnxi-Wu/scripts/deploy/deploy-with-ssh-key.ps1
WuYongJie f646b71813
Some checks failed
CI Check / check (push) Has been cancelled
chore: 初始化本地仓库并同步最近改动
2025-11-18 17:50:16 +08:00

239 lines
7.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.

# 使用 SSH 密钥的部署脚本(更安全)
param(
[string]$Server = "45.249.208.118",
[string]$User = "root",
[string]$SshKeyPath = "$env:USERPROFILE\.ssh\id_rsa", # 默认 SSH 密钥路径
[string]$ProjectPath = "/root/youyidian-3d",
[switch]$NoCache = $false
)
$ErrorActionPreference = "Stop"
Write-Host "========================================" -ForegroundColor Cyan
Write-Host " 安全部署脚本 - 使用 SSH 密钥" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan
Write-Host ""
# 检查工具
$plinkPath = "C:\Program Files\PuTTY\plink.exe"
$pscpPath = "C:\Program Files\PuTTY\pscp.exe"
if (-not (Test-Path $plinkPath)) {
Write-Host "错误: 未找到 plink.exe,请安装 PuTTY" -ForegroundColor Red
exit 1
}
# 检查 SSH 密钥文件
if (-not (Test-Path $SshKeyPath)) {
Write-Host "错误: 未找到 SSH 密钥文件: $SshKeyPath" -ForegroundColor Red
Write-Host ""
Write-Host "请执行以下步骤创建 SSH 密钥:" -ForegroundColor Yellow
Write-Host " 1. 生成密钥对: ssh-keygen -t rsa -b 4096 -C `"deploy@youyidian`"" -ForegroundColor Gray
Write-Host " 2. 将公钥复制到服务器: ssh-copy-id -i ~/.ssh/id_rsa.pub ${User}@${Server}" -ForegroundColor Gray
Write-Host " 3. 或者手动复制公钥内容到服务器的 ~/.ssh/authorized_keys" -ForegroundColor Gray
Write-Host ""
Write-Host "如果你使用 PuTTY,可以:" -ForegroundColor Yellow
Write-Host " 1. 使用 PuTTYgen 生成密钥对" -ForegroundColor Gray
Write-Host " 2. 将公钥添加到服务器的 ~/.ssh/authorized_keys" -ForegroundColor Gray
Write-Host " 3. 在 Pageant 中加载私钥,或使用 -i 参数指定私钥文件" -ForegroundColor Gray
exit 1
}
Write-Host "使用 SSH 密钥: $SshKeyPath" -ForegroundColor Green
Write-Host ""
# 需要上传的关键文件
$filesToUpload = @(
"app/page.tsx",
"app/login/page.tsx",
"app/api/network-status/route.ts",
"next.config.js",
"README.md",
"lib/config.ts",
"lib/configLoader.ts",
"config-bianliang.env",
"Dockerfile",
"docker-compose.yml",
"package.json",
"package-lock.json"
)
# 检查文件是否存在
$missingFiles = @()
foreach ($file in $filesToUpload) {
if (-not (Test-Path $file)) {
$missingFiles += $file
}
}
if ($missingFiles.Count -gt 0) {
Write-Host "警告: 以下文件不存在,将跳过:" -ForegroundColor Yellow
$missingFiles | ForEach-Object { Write-Host " - $_" -ForegroundColor Yellow }
}
# 上传文件
Write-Host "[1/5] 上传文件到服务器..." -ForegroundColor Yellow
$uploadedCount = 0
foreach ($file in $filesToUpload) {
if (Test-Path $file) {
$remotePath = "$ProjectPath/$file"
$remoteDir = Split-Path $remotePath -Parent
# 确保远程目录存在
& $plinkPath -ssh -i $SshKeyPath -batch "${User}@${Server}" "mkdir -p `"$remoteDir`"" | Out-Null
# 上传文件
& $pscpPath -i $SshKeyPath -batch -q $file "${User}@${Server}:$remotePath" 2>&1 | Out-Null
if ($LASTEXITCODE -eq 0) {
$uploadedCount++
Write-Host " ✓ $file" -ForegroundColor Green
} else {
Write-Host " ✗ $file (上传失败)" -ForegroundColor Red
}
}
}
Write-Host "已上传 $uploadedCount/$($filesToUpload.Count) 个文件" -ForegroundColor $(if ($uploadedCount -eq $filesToUpload.Count) { "Green" } else { "Yellow" })
# 创建部署脚本
Write-Host "[2/5] 创建部署脚本..." -ForegroundColor Yellow
$buildFlag = if ($NoCache) { "--no-cache" } else { "" }
$timestamp = Get-Date -Format "yyyyMMdd-HHmmss"
$deployScript = @"
#!/bin/bash
set -e
cd $ProjectPath
echo "========================================"
echo "开始部署..."
echo "========================================"
# 备份数据
echo "[1/6] 备份数据..."
if [ -d "uploads" ]; then
mkdir -p backups
backup_dir="backups/uploads-$(date +%Y%m%d-%H%M%S)"
cp -r uploads "`$backup_dir" 2>/dev/null || true
echo " ✓ 上传目录已备份到 `$backup_dir"
fi
# 检查环境
echo "[2/6] 检查环境..."
if ! command -v docker &> /dev/null; then
echo "错误: Docker 未安装" >&2
exit 1
fi
if docker compose version &> /dev/null; then
DOCKER_COMPOSE="docker compose"
elif docker-compose version &> /dev/null; then
DOCKER_COMPOSE="docker-compose"
else
echo "错误: Docker Compose 未安装" >&2
exit 1
fi
echo " ✓ 使用: `$DOCKER_COMPOSE"
# 停止旧容器
echo "[3/6] 停止旧容器..."
`$DOCKER_COMPOSE down --timeout 30 2>/dev/null || true
echo " ✓ 旧容器已停止"
# 构建并启动
echo "[4/6] 构建并启动容器..."
if [ -n "$buildFlag" ]; then
echo " ⚠ 使用 --no-cache 模式"
`$DOCKER_COMPOSE build $buildFlag app && `$DOCKER_COMPOSE up -d app
else
echo " ✓ 使用智能构建缓存"
`$DOCKER_COMPOSE up -d --build app
fi
if [ `$? -ne 0 ]; then
echo "错误: 容器构建或启动失败" >&2
exit 1
fi
echo " ✓ 容器构建并启动完成"
# 等待容器就绪
echo "[5/6] 等待容器就绪..."
sleep 10
max_attempts=30
attempt=0
while [ `$attempt -lt `$max_attempts ]; do
if `$DOCKER_COMPOSE ps app | grep -q "Up"; then
echo " ✓ 容器运行中"
break
fi
attempt=`$((attempt + 1))
sleep 2
done
# 数据库迁移
echo "[6/6] 检查数据库迁移..."
if [ -f prisma/schema.prisma ]; then
`$DOCKER_COMPOSE exec -T app npx prisma db push --accept-data-loss --schema=/app/prisma/schema.prisma 2>/dev/null || echo " ⚠ 数据库迁移跳过或已完成"
fi
# 显示结果
echo ""
echo "========================================"
echo "部署完成!"
echo "========================================"
echo ""
echo "容器状态:"
`$DOCKER_COMPOSE ps
echo ""
echo "应用日志(最后 30 行):"
`$DOCKER_COMPOSE logs app --tail=30
"@
$localDeployScript = Join-Path $env:TEMP "deploy-ssh-$timestamp.sh"
$utf8NoBom = New-Object System.Text.UTF8Encoding $false
[System.IO.File]::WriteAllText($localDeployScript, $deployScript, $utf8NoBom)
# 上传部署脚本
Write-Host "[3/5] 上传部署脚本..." -ForegroundColor Yellow
$remoteDeployScript = "/tmp/deploy-ssh-$timestamp.sh"
& $pscpPath -i $SshKeyPath -batch $localDeployScript "${User}@${Server}:$remoteDeployScript"
if ($LASTEXITCODE -ne 0) {
Write-Host "上传部署脚本失败" -ForegroundColor Red
exit 1
}
Write-Host " ✓ 部署脚本已上传" -ForegroundColor Green
# 执行部署
Write-Host "[4/5] 执行部署..." -ForegroundColor Yellow
Write-Host ""
& $plinkPath -ssh -i $SshKeyPath -batch "${User}@${Server}" "chmod +x $remoteDeployScript; bash $remoteDeployScript; rm -f $remoteDeployScript"
$deployExitCode = $LASTEXITCODE
# 清理
Remove-Item $localDeployScript -Force -ErrorAction SilentlyContinue
if ($deployExitCode -ne 0) {
Write-Host ""
Write-Host "部署失败,退出码: $deployExitCode" -ForegroundColor Red
exit 1
}
Write-Host ""
Write-Host "========================================" -ForegroundColor Green
Write-Host " 部署成功完成!" -ForegroundColor Green
Write-Host "========================================" -ForegroundColor Green
Write-Host ""
Write-Host "提示:" -ForegroundColor Yellow
Write-Host " - 使用 -SshKeyPath 参数指定自定义 SSH 密钥路径" -ForegroundColor Gray
Write-Host " - 使用 -NoCache 参数可以强制重新构建" -ForegroundColor Gray
Write-Host ""