# ============================================ # 3D家具安装展示系统 - 智能缓存部署脚本 # 优先使用本地缓存,提升构建和部署速度 # ============================================ param( [ValidateSet("dev", "prod", "cached")] [string]$Mode = "cached", [string]$SourcePath = "..\flnxi_sucai", [switch]$SkipCache, [switch]$Force, [switch]$Rebuild ) # 设置错误处理 $ErrorActionPreference = "Stop" # 颜色输出函数 function Write-ColorOutput { param([string]$Message, [string]$Color = "White") $colors = @{ "Red" = [ConsoleColor]::Red "Green" = [ConsoleColor]::Green "Yellow" = [ConsoleColor]::Yellow "Blue" = [ConsoleColor]::Blue "Cyan" = [ConsoleColor]::Cyan "White" = [ConsoleColor]::White "Magenta" = [ConsoleColor]::Magenta } Write-Host $Message -ForegroundColor $colors[$Color] } # 显示横幅 function Show-Banner { Write-ColorOutput "╔══════════════════════════════════════════════════════════════╗" "Cyan" Write-ColorOutput "║ 3D家具安装展示系统 ║" "Cyan" Write-ColorOutput "║ 智能缓存部署脚本 v1.0 ║" "Cyan" Write-ColorOutput "║ ║" "Cyan" Write-ColorOutput "║ 🚀 优先使用本地缓存,加速构建部署 ║" "Cyan" Write-ColorOutput "║ 📦 自动管理Docker镜像和npm依赖 ║" "Cyan" Write-ColorOutput "║ 🔧 智能检测和配置优化 ║" "Cyan" Write-ColorOutput "╚══════════════════════════════════════════════════════════════╝" "Cyan" Write-ColorOutput "" } # 检查系统环境 function Test-SystemRequirements { Write-ColorOutput "🔍 检查系统环境..." "Blue" # 检查Docker try { $dockerVersion = docker --version Write-ColorOutput "✅ Docker: $dockerVersion" "Green" } catch { Write-ColorOutput "❌ Docker未安装或未运行" "Red" throw "请先安装并启动Docker" } # 检查Docker Compose try { $composeVersion = docker-compose --version Write-ColorOutput "✅ Docker Compose: $composeVersion" "Green" } catch { Write-ColorOutput "❌ Docker Compose未安装" "Red" throw "请先安装Docker Compose" } # 检查Node.js(可选,用于本地开发) try { $nodeVersion = node --version Write-ColorOutput "✅ Node.js: $nodeVersion" "Green" } catch { Write-ColorOutput "⚠️ Node.js未安装(Docker模式不需要)" "Yellow" } # 检查可用磁盘空间 $freeSpace = Get-WmiObject -Class Win32_LogicalDisk | Where-Object {$_.DeviceID -eq "C:"} | Select-Object -ExpandProperty FreeSpace $freeSpaceGB = [math]::Round($freeSpace / 1GB, 2) if ($freeSpaceGB -lt 5) { Write-ColorOutput "⚠️ 磁盘空间不足: ${freeSpaceGB}GB,建议至少5GB" "Yellow" } else { Write-ColorOutput "✅ 磁盘空间: ${freeSpaceGB}GB" "Green" } } # 设置缓存环境 function Setup-CacheEnvironment { if ($SkipCache) { Write-ColorOutput "⏭️ 跳过缓存设置" "Yellow" return } Write-ColorOutput "🔧 设置缓存环境..." "Blue" # 运行缓存管理器 if (Test-Path "scripts\cache-manager.ps1") { try { & "scripts\cache-manager.ps1" -Action "setup" -SourcePath $SourcePath Write-ColorOutput "✅ 缓存环境设置完成" "Green" } catch { Write-ColorOutput "⚠️ 缓存设置失败,将使用网络下载: $($_.Exception.Message)" "Yellow" } } else { Write-ColorOutput "⚠️ 缓存管理器不存在,跳过缓存设置" "Yellow" } } # 检查并加载Docker镜像 function Load-DockerImages { if ($SkipCache) { return } Write-ColorOutput "🐳 检查Docker镜像..." "Blue" # 检查关键镜像是否存在 $requiredImages = @( "node:18-alpine", "postgres:15-alpine", "minio/minio:latest", "minio/mc:latest" ) foreach ($image in $requiredImages) { try { docker inspect $image | Out-Null Write-ColorOutput "✅ 镜像已存在: $image" "Green" } catch { Write-ColorOutput "📥 镜像不存在,尝试从缓存加载: $image" "Yellow" # 尝试从缓存加载 $imageName = $image.Replace(":", "-").Replace("/", "-") $cacheFile = "cache\docker-images\$imageName.tar" if (Test-Path $cacheFile) { try { Write-ColorOutput "📦 从缓存加载: $cacheFile" "Cyan" docker load -i $cacheFile Write-ColorOutput "✅ 缓存镜像加载成功: $image" "Green" } catch { Write-ColorOutput "⚠️ 缓存镜像加载失败,将在线下载: $image" "Yellow" } } else { Write-ColorOutput "⚠️ 缓存文件不存在,将在线下载: $image" "Yellow" } } } } # 选择Docker Compose文件 function Get-ComposeFile { switch ($Mode) { "dev" { return "docker-compose.dev.yml" } "prod" { return "docker-compose.prod.yml" } "cached" { return "docker-compose.cached.yml" } default { return "docker-compose.cached.yml" } } } # 停止现有服务 function Stop-ExistingServices { Write-ColorOutput "🛑 停止现有服务..." "Blue" $composeFile = Get-ComposeFile try { docker-compose -f $composeFile down --remove-orphans Write-ColorOutput "✅ 现有服务已停止" "Green" } catch { Write-ColorOutput "⚠️ 停止服务时出现警告: $($_.Exception.Message)" "Yellow" } # 清理悬空镜像(如果强制重建) if ($Rebuild) { Write-ColorOutput "🧹 清理悬空镜像..." "Blue" try { docker image prune -f Write-ColorOutput "✅ 悬空镜像已清理" "Green" } catch { Write-ColorOutput "⚠️ 清理镜像失败: $($_.Exception.Message)" "Yellow" } } } # 构建和启动服务 function Start-Services { Write-ColorOutput "🚀 构建和启动服务..." "Blue" $composeFile = Get-ComposeFile Write-ColorOutput "📋 使用配置文件: $composeFile" "Cyan" # 构建参数 $buildArgs = @() if ($Rebuild) { $buildArgs += "--build" $buildArgs += "--no-cache" } try { # 启动服务 if ($buildArgs.Count -gt 0) { docker-compose -f $composeFile up -d @buildArgs } else { docker-compose -f $composeFile up -d } Write-ColorOutput "✅ 服务启动成功" "Green" } catch { Write-ColorOutput "❌ 服务启动失败: $($_.Exception.Message)" "Red" throw } } # 等待服务就绪 function Wait-ForServices { Write-ColorOutput "⏳ 等待服务就绪..." "Blue" $maxWaitTime = 120 # 最大等待2分钟 $waitInterval = 5 # 每5秒检查一次 $elapsed = 0 while ($elapsed -lt $maxWaitTime) { try { # 检查健康检查端点 $response = Invoke-WebRequest -Uri "http://localhost:3000/api/health" -TimeoutSec 3 -UseBasicParsing if ($response.StatusCode -eq 200) { Write-ColorOutput "✅ 应用服务就绪" "Green" return $true } } catch { # 继续等待 } Write-ColorOutput "⏳ 等待中... ($elapsed/$maxWaitTime 秒)" "Yellow" Start-Sleep $waitInterval $elapsed += $waitInterval } Write-ColorOutput "⚠️ 服务启动超时,请检查日志" "Yellow" return $false } # 显示服务状态 function Show-ServiceStatus { Write-ColorOutput "📊 服务状态:" "Blue" $composeFile = Get-ComposeFile try { docker-compose -f $composeFile ps Write-ColorOutput "" # 显示访问地址 Write-ColorOutput "🌐 访问地址:" "Green" Write-ColorOutput " • 主应用: http://localhost:3000" "Cyan" Write-ColorOutput " • 健康检查: http://localhost:3000/api/health" "Cyan" Write-ColorOutput " • MinIO管理: http://localhost:9001 (minioadmin/minioadmin)" "Cyan" Write-ColorOutput " • 数据库: localhost:5432 (furniture_user/furniture_pass_2024)" "Cyan" } catch { Write-ColorOutput "❌ 获取服务状态失败: $($_.Exception.Message)" "Red" } } # 显示日志 function Show-Logs { Write-ColorOutput "📋 最近日志:" "Blue" $composeFile = Get-ComposeFile try { docker-compose -f $composeFile logs --tail=20 } catch { Write-ColorOutput "❌ 获取日志失败: $($_.Exception.Message)" "Red" } } # 主函数 function Main { try { Show-Banner Write-ColorOutput "🎯 部署模式: $Mode" "Magenta" Write-ColorOutput "📁 源路径: $SourcePath" "Magenta" Write-ColorOutput "" # 1. 检查系统环境 Test-SystemRequirements Write-ColorOutput "" # 2. 设置缓存环境 Setup-CacheEnvironment Write-ColorOutput "" # 3. 加载Docker镜像 Load-DockerImages Write-ColorOutput "" # 4. 停止现有服务 Stop-ExistingServices Write-ColorOutput "" # 5. 启动服务 Start-Services Write-ColorOutput "" # 6. 等待服务就绪 $isReady = Wait-ForServices Write-ColorOutput "" # 7. 显示状态 Show-ServiceStatus Write-ColorOutput "" if ($isReady) { Write-ColorOutput "🎉 部署完成!系统已就绪" "Green" Write-ColorOutput "" Write-ColorOutput "💡 提示:" "Yellow" Write-ColorOutput " • 使用 'docker-compose -f $(Get-ComposeFile) logs -f' 查看实时日志" "Cyan" Write-ColorOutput " • 使用 'docker-compose -f $(Get-ComposeFile) down' 停止服务" "Cyan" Write-ColorOutput " • 使用 'scripts\cache-manager.ps1 -Action save-images' 保存镜像到缓存" "Cyan" } else { Write-ColorOutput "⚠️ 部署完成但服务可能未完全就绪,请检查日志" "Yellow" Show-Logs } } catch { Write-ColorOutput "❌ 部署失败: $($_.Exception.Message)" "Red" Write-ColorOutput "" Write-ColorOutput "🔧 故障排除:" "Yellow" Write-ColorOutput " • 检查Docker是否正常运行" "Cyan" Write-ColorOutput " • 检查端口是否被占用 (3000, 5432, 9000, 9001)" "Cyan" Write-ColorOutput " • 使用 -Rebuild 参数强制重新构建" "Cyan" Write-ColorOutput " • 查看详细日志: docker-compose -f $(Get-ComposeFile) logs" "Cyan" exit 1 } } # 执行主函数 Main