furniture-3d-system-Wu/scripts/deploy-feiniu.ps1
WuYongJie 5821d73291 初始提交:3D家具安装展示系统
包含:
- furniture-3d-system:Next.js 16 全栈应用(资产中心、产品管理、3D装配动画)
- autocad-plugin:AutoCAD 家具导出插件源码
- 资产中心改造:编辑弹窗化、删除功能、Toast反馈、自定义Select组件

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 14:00:19 +08:00

254 lines
9.3 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.

# 飞牛OS部署脚本
# 用途:一键部署到飞牛OS服务器 (192.168.42.252)
# 使用:.\scripts\deploy-feiniu.ps1
param(
[string]$ServerIP = "192.168.42.252",
[string]$ServerUser = "admin",
[string]$ServerPassword = "admin123",
[string]$RemotePath = "/opt/furniture-3d-system",
[switch]$SkipUpload = $false,
[switch]$SkipBuild = $false
)
Write-Host "=== 飞牛OS部署脚本 ===" -ForegroundColor Cyan
Write-Host "目标服务器: $ServerIP" -ForegroundColor Yellow
Write-Host "部署路径: $RemotePath`n" -ForegroundColor Yellow
# 检查必要的工具
Write-Host "检查必要工具..." -ForegroundColor Yellow
# 检查SSH客户端(Windows 10+自带OpenSSH)
$sshAvailable = Get-Command ssh -ErrorAction SilentlyContinue
if (-not $sshAvailable) {
Write-Host "❌ 未找到SSH客户端" -ForegroundColor Red
Write-Host "请安装OpenSSH客户端或使用WinSCP等工具手动上传文件" -ForegroundColor Yellow
exit 1
}
Write-Host "✅ SSH客户端可用" -ForegroundColor Green
# 检查SCP(用于文件传输)
$scpAvailable = Get-Command scp -ErrorAction SilentlyContinue
if (-not $scpAvailable) {
Write-Host "⚠️ 未找到SCP客户端,将使用SSH命令传输" -ForegroundColor Yellow
$useScp = $false
} else {
Write-Host "✅ SCP客户端可用" -ForegroundColor Green
$useScp = $true
}
# 检查项目目录
Write-Host "`n检查项目目录..." -ForegroundColor Yellow
$projectPath = "d:\3danzhuang\furniture-3d-system"
if (-not (Test-Path $projectPath)) {
Write-Host "❌ 项目目录不存在: $projectPath" -ForegroundColor Red
exit 1
}
Write-Host "✅ 项目目录存在: $projectPath" -ForegroundColor Green
# 检查必要的文件
$requiredFiles = @(
"docker-compose.prod.yml",
"Dockerfile",
"package.json"
)
foreach ($file in $requiredFiles) {
$filePath = Join-Path $projectPath $file
if (-not (Test-Path $filePath)) {
Write-Host "❌ 缺少必要文件: $file" -ForegroundColor Red
exit 1
}
}
Write-Host "✅ 必要文件检查通过" -ForegroundColor Green
# 测试SSH连接
Write-Host "`n测试SSH连接..." -ForegroundColor Yellow
$sshTest = ssh -o StrictHostKeyChecking=no -o ConnectTimeout=5 "$ServerUser@$ServerIP" "echo 'SSH连接成功'" 2>&1
if ($LASTEXITCODE -ne 0) {
Write-Host "❌ SSH连接失败" -ForegroundColor Red
Write-Host "请检查:" -ForegroundColor Yellow
Write-Host " 1. 服务器IP地址是否正确: $ServerIP" -ForegroundColor Gray
Write-Host " 2. 用户名和密码是否正确" -ForegroundColor Gray
Write-Host " 3. 服务器是否可访问" -ForegroundColor Gray
Write-Host "`n提示: 首次连接可能需要手动输入密码" -ForegroundColor Yellow
exit 1
}
Write-Host "✅ SSH连接成功" -ForegroundColor Green
# 上传文件(如果未跳过)
if (-not $SkipUpload) {
Write-Host "`n上传项目文件到服务器..." -ForegroundColor Yellow
# 创建临时压缩包
$tempZip = "$env:TEMP\furniture-3d-system-$(Get-Date -Format 'yyyyMMdd-HHmmss').zip"
Write-Host "创建临时压缩包: $tempZip" -ForegroundColor Gray
# 排除不需要的文件
$excludePatterns = @(
"node_modules",
".next",
".git",
"backups",
"*.log"
)
# 使用PowerShell压缩(需要.NET 4.5+)
try {
Add-Type -AssemblyName System.IO.Compression.FileSystem
[System.IO.Compression.ZipFile]::CreateFromDirectory($projectPath, $tempZip)
Write-Host "✅ 压缩包创建成功" -ForegroundColor Green
} catch {
Write-Host "❌ 压缩失败: $_" -ForegroundColor Red
Write-Host "请手动打包项目文件并上传到服务器" -ForegroundColor Yellow
exit 1
}
# 上传压缩包
Write-Host "上传压缩包到服务器..." -ForegroundColor Gray
if ($useScp) {
# 使用SCP上传
scp -o StrictHostKeyChecking=no "$tempZip" "${ServerUser}@${ServerIP}:${RemotePath}.zip" 2>&1 | Out-Null
} else {
# 使用SSH + base64传输(备用方案)
Write-Host "⚠️ SCP不可用,请手动上传压缩包到服务器" -ForegroundColor Yellow
Write-Host "压缩包位置: $tempZip" -ForegroundColor Gray
Write-Host "服务器路径: $RemotePath.zip" -ForegroundColor Gray
$manualUpload = Read-Host "已手动上传?(Y/N)"
if ($manualUpload -ne 'Y' -and $manualUpload -ne 'y') {
exit 0
}
}
if ($LASTEXITCODE -eq 0 -or $manualUpload -eq 'Y' -or $manualUpload -eq 'y') {
Write-Host "✅ 文件上传成功" -ForegroundColor Green
# 在服务器上解压
Write-Host "在服务器上解压文件..." -ForegroundColor Gray
ssh -o StrictHostKeyChecking=no "$ServerUser@$ServerIP" "mkdir -p $RemotePath && unzip -q -o ${RemotePath}.zip -d $RemotePath && rm ${RemotePath}.zip" 2>&1 | Out-Null
Write-Host "✅ 文件解压完成" -ForegroundColor Green
} else {
Write-Host "❌ 文件上传失败" -ForegroundColor Red
Write-Host "请手动上传项目文件到服务器: $RemotePath" -ForegroundColor Yellow
exit 1
}
# 清理临时文件
Remove-Item $tempZip -ErrorAction SilentlyContinue
} else {
Write-Host "`n跳过文件上传(使用 -SkipUpload 参数)" -ForegroundColor Yellow
}
# 在服务器上执行部署
Write-Host "`n在服务器上执行部署..." -ForegroundColor Yellow
# 创建部署脚本(使用单引号here-string避免PowerShell解析bash变量)
$deployScript = @'
#!/bin/bash
set -e
REMOTE_PATH="'@ + $RemotePath + @'"
SERVER_IP="'@ + $ServerIP + @'"
cd "$REMOTE_PATH"
echo "=== 检查Docker环境 ==="
docker --version || { echo "❌ Docker未安装"; exit 1; }
docker-compose --version || { echo "❌ Docker Compose未安装"; exit 1; }
echo "=== 检查环境变量文件 ==="
if [ ! -f .env ]; then
echo "⚠️ .env文件不存在,创建默认配置..."
cat > .env << EOF
DATABASE_URL=postgresql://furniture:furniture123@postgres:5432/furniture_db?schema=public
S3_ENDPOINT=http://minio:9000
S3_PUBLIC_ENDPOINT=http://${SERVER_IP}:9000
S3_REGION=us-east-1
S3_ACCESS_KEY=minioadmin
S3_SECRET_KEY=minioadmin123
S3_BUCKET=furniture-3d-models
JWT_SECRET=change-me-in-production-use-strong-random-string
NODE_ENV=production
NEXT_TELEMETRY_DISABLED=1
PORT=3000
WEB_PORT=3000
EOF
echo "✅ 已创建默认.env文件"
echo "⚠️ 请修改.env文件中的JWT_SECRET为强密码!"
else
echo "✅ .env文件已存在"
fi
echo "=== 停止现有服务 ==="
docker-compose -f docker-compose.prod.yml down || true
echo "=== 构建并启动服务 ==="
if [ "$SKIP_BUILD" = "true" ]; then
echo "跳过构建,直接启动..."
docker-compose -f docker-compose.prod.yml up -d
else
echo "构建应用镜像..."
docker-compose -f docker-compose.prod.yml build app
echo "启动所有服务..."
docker-compose -f docker-compose.prod.yml up -d
fi
echo "=== 等待服务启动 ==="
sleep 10
echo "=== 检查服务状态 ==="
docker-compose -f docker-compose.prod.yml ps
echo "=== 检查健康状态 ==="
sleep 5
curl -f http://localhost:3000/api/health || echo "⚠️ 健康检查失败,请查看日志"
echo ""
echo "=== 部署完成 ==="
echo "访问地址: http://${SERVER_IP}:3001"
echo "MinIO控制台: http://${SERVER_IP}:9003"
echo ""
echo "查看日志: docker-compose -f docker-compose.prod.yml logs -f"
'@
# 将部署脚本写入临时文件并上传
$scriptFile = "$env:TEMP\deploy-feiniu-$(Get-Date -Format 'yyyyMMdd-HHmmss').sh"
$deployScript | Out-File -FilePath $scriptFile -Encoding UTF8
Write-Host "上传部署脚本..." -ForegroundColor Gray
if ($useScp) {
scp -o StrictHostKeyChecking=no "$scriptFile" "${ServerUser}@${ServerIP}:/tmp/deploy-feiniu.sh" 2>&1 | Out-Null
} else {
Write-Host "⚠️ 请手动上传部署脚本到服务器: $scriptFile" -ForegroundColor Yellow
$manualScript = Read-Host "已手动上传?(Y/N)"
if ($manualScript -ne 'Y' -and $manualScript -ne 'y') {
exit 0
}
}
# 执行部署脚本
Write-Host "执行部署脚本..." -ForegroundColor Gray
$buildFlag = if ($SkipBuild) { "true" } else { "false" }
ssh -o StrictHostKeyChecking=no "$ServerUser@$ServerIP" "chmod +x /tmp/deploy-feiniu.sh && SKIP_BUILD=$buildFlag bash /tmp/deploy-feiniu.sh"
if ($LASTEXITCODE -eq 0) {
Write-Host "`n✅ 部署完成!" -ForegroundColor Green
Write-Host "`n访问地址:" -ForegroundColor Cyan
Write-Host " 应用: http://$ServerIP:3000" -ForegroundColor White
Write-Host " MinIO控制台: http://$ServerIP:9001" -ForegroundColor White
Write-Host "`n常用命令:" -ForegroundColor Cyan
Write-Host " 查看日志: ssh $ServerUser@$ServerIP 'cd $RemotePath && docker-compose -f docker-compose.prod.yml logs -f'" -ForegroundColor Gray
Write-Host " 查看状态: ssh $ServerUser@$ServerIP 'cd $RemotePath && docker-compose -f docker-compose.prod.yml ps'" -ForegroundColor Gray
Write-Host " 停止服务: ssh $ServerUser@$ServerIP 'cd $RemotePath && docker-compose -f docker-compose.prod.yml down'" -ForegroundColor Gray
} else {
Write-Host "`n❌ 部署过程中出现错误" -ForegroundColor Red
Write-Host "请查看服务器日志进行排查" -ForegroundColor Yellow
exit 1
}
# 清理临时文件
Remove-Item $scriptFile -ErrorAction SilentlyContinue
Write-Host "`n✅ 脚本执行完成!" -ForegroundColor Green