| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 |
- # ============================================================
- # LambdaAgentPaaS — Windows 一键启动脚本 (PowerShell)
- #
- # 用法:
- # .\deploy\start.ps1 # 正常启动
- # .\deploy\start.ps1 -Build # 强制重新构建镜像
- # .\deploy\start.ps1 -Reset # 清除所有数据重新初始化
- #
- # 要求: Docker Desktop for Windows 已安装并运行
- # PowerShell 5.1 或 PowerShell 7+
- # ============================================================
- param(
- [switch]$Build,
- [switch]$Reset
- )
- $ErrorActionPreference = "Stop"
- # ── 路径常量 ────────────────────────────────────────────────
- $ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
- $ProjectDir = Split-Path -Parent $ScriptDir
- $DataDir = Join-Path $env:USERPROFILE ".agentpaas\data"
- $EnvFile = Join-Path $env:USERPROFILE ".agentpaas\.env"
- $AppPort = if ($env:AGENTPAAS_PORT) { $env:AGENTPAAS_PORT } else { "8000" }
- $AppUrl = "http://localhost:$AppPort"
- # ── 颜色输出辅助函数 ─────────────────────────────────────────
- function Write-Info { param($msg) Write-Host "ℹ $msg" -ForegroundColor Cyan }
- function Write-Success { param($msg) Write-Host "✅ $msg" -ForegroundColor Green }
- function Write-Warn { param($msg) Write-Host "⚠️ $msg" -ForegroundColor Yellow }
- function Write-Err { param($msg) Write-Host "❌ $msg" -ForegroundColor Red }
- function Write-Header { param($msg) Write-Host "`n=== $msg ===`n" -ForegroundColor Magenta }
- # ── 检查 Docker ──────────────────────────────────────────────
- function Check-Docker {
- Write-Header "检查 Docker 环境"
- if (-not (Get-Command docker -ErrorAction SilentlyContinue)) {
- Write-Err "未找到 Docker。请先安装 Docker Desktop:"
- Write-Host " https://docs.docker.com/desktop/install/windows-install/"
- $open = Read-Host "是否现在打开下载页面? (Y/n)"
- if ($open -ne 'n' -and $open -ne 'N') {
- Start-Process "https://docs.docker.com/desktop/install/windows-install/"
- }
- exit 1
- }
- $dockerRunning = $false
- try {
- docker info 2>&1 | Out-Null
- $dockerRunning = $true
- } catch {}
- if (-not $dockerRunning) {
- Write-Info "Docker Desktop 未运行,尝试启动..."
- $dockerDesktopPaths = @(
- "$env:ProgramFiles\Docker\Docker\Docker Desktop.exe",
- "$env:LOCALAPPDATA\Programs\Docker\Docker\Docker Desktop.exe"
- )
- $launched = $false
- foreach ($path in $dockerDesktopPaths) {
- if (Test-Path $path) {
- Start-Process $path
- $launched = $true
- break
- }
- }
- if (-not $launched) {
- Write-Warn "无法自动启动 Docker Desktop,请手动启动后重试。"
- exit 1
- }
- Write-Host -NoNewline "等待 Docker 就绪"
- $waited = 0
- do {
- Start-Sleep -Seconds 2
- $waited += 2
- Write-Host -NoNewline "."
- if ($waited -gt 60) {
- Write-Host ""
- Write-Err "Docker 启动超时(60s)。请手动启动 Docker Desktop 后重试。"
- exit 1
- }
- try { docker info 2>&1 | Out-Null; break } catch {}
- } while ($true)
- Write-Host ""
- Write-Success "Docker 已就绪"
- }
- # 检测 compose 命令
- $script:ComposeCmd = $null
- try { docker compose version 2>&1 | Out-Null; $script:ComposeCmd = "docker compose" } catch {}
- if (-not $script:ComposeCmd) {
- if (Get-Command docker-compose -ErrorAction SilentlyContinue) {
- $script:ComposeCmd = "docker-compose"
- } else {
- Write-Err "未找到 docker compose。请升级 Docker Desktop 到最新版本。"
- exit 1
- }
- }
- Write-Success "Docker 环境检查通过"
- }
- # ── 初始化数据目录 ────────────────────────────────────────────
- function Init-DataDir {
- $dirs = @(
- $DataDir,
- (Join-Path $DataDir "instances"),
- (Join-Path $DataDir "knowledge_bases"),
- (Join-Path $DataDir "logs")
- )
- foreach ($dir in $dirs) {
- if (-not (Test-Path $dir)) {
- New-Item -ItemType Directory -Path $dir -Force | Out-Null
- }
- }
- }
- # ── 初始化 .env 配置 ─────────────────────────────────────────
- function Init-Env {
- $configDir = Split-Path -Parent $EnvFile
- if (-not (Test-Path $configDir)) {
- New-Item -ItemType Directory -Path $configDir -Force | Out-Null
- }
- if ((Test-Path $EnvFile) -and (-not $Reset)) {
- return
- }
- Write-Header "🔧 首次配置初始化"
- # 复制模板
- Copy-Item (Join-Path $ProjectDir ".env.template") $EnvFile -Force
- # 生成 MASTER_KEY
- $masterKey = -join ((1..32) | ForEach-Object {
- [System.Security.Cryptography.RandomNumberGenerator]::GetBytes(1) |
- ForEach-Object { $_.ToString("x2") }
- })
- # 更新 .env 文件
- $envContent = Get-Content $EnvFile
- $envContent = $envContent -replace "^AGENTPAAS_DATA_DIR=.*", "AGENTPAAS_DATA_DIR=$DataDir"
- $envContent = $envContent -replace "^AGENTPAAS_MASTER_KEY=.*", "AGENTPAAS_MASTER_KEY=$masterKey"
- $envContent | Set-Content $EnvFile -Encoding UTF8
- Write-Success "配置文件已创建: $EnvFile"
- Write-Host ""
- Write-Warn "请编辑配置文件,填写至少一个 LLM API Key:"
- Write-Host " DASHSCOPE_API_KEY= (阿里云百炼,国内推荐)"
- Write-Host " ANTHROPIC_API_KEY= (Claude)"
- Write-Host " OPENAI_API_KEY= (GPT)"
- Write-Host ""
- $open = Read-Host "是否现在打开配置文件编辑? (Y/n)"
- if ($open -ne 'n' -and $open -ne 'N') {
- # 尝试用记事本打开
- Start-Process notepad $EnvFile
- Write-Host "配置完成后,请重新运行此脚本。"
- exit 0
- }
- }
- # ── 加载 .env 文件为环境变量 ─────────────────────────────────
- function Load-EnvFile {
- if (-not (Test-Path $EnvFile)) { return }
- Get-Content $EnvFile | ForEach-Object {
- if ($_ -match "^\s*([^#][^=]+)=(.*)$") {
- $name = $matches[1].Trim()
- $value = $matches[2].Trim()
- if ($value -ne "" -and -not [System.Environment]::GetEnvironmentVariable($name)) {
- [System.Environment]::SetEnvironmentVariable($name, $value, "Process")
- }
- }
- }
- }
- # ── 检查 API Keys ────────────────────────────────────────────
- function Check-ApiKeys {
- $keyVars = @("DASHSCOPE_API_KEY","OPENAI_API_KEY","ANTHROPIC_API_KEY",
- "DEEPSEEK_API_KEY","ZHIPU_API_KEY","MOONSHOT_API_KEY")
- $hasKey = $false
- foreach ($var in $keyVars) {
- $val = [System.Environment]::GetEnvironmentVariable($var)
- if ($val -and $val.Trim() -ne "") { $hasKey = $true; break }
- }
- if (-not $hasKey) {
- Write-Warn "未检测到任何 LLM API Key。Agent 功能将不可用。"
- Write-Host "请在 $EnvFile 中配置至少一个 API Key。"
- Write-Host ""
- $cont = Read-Host "继续启动? (y/N)"
- if ($cont -ne 'y' -and $cont -ne 'Y') { exit 0 }
- }
- }
- # ── 启动服务 ─────────────────────────────────────────────────
- function Start-Services {
- Write-Header "🚀 启动 LambdaAgentPaaS"
- # 将 Windows 路径转换为 Docker 可接受格式
- # Docker Desktop (WSL2) 可以直接处理 Windows 路径,但统一转换更安全
- $env:AGENTPAAS_DATA_DIR = $DataDir
- Set-Location $ProjectDir
- if ($Reset) {
- Write-Info "清除旧容器..."
- Invoke-Expression "$($script:ComposeCmd) down --remove-orphans" 2>$null
- docker rmi lambdagentpaas:latest 2>$null
- }
- $buildArg = if ($Build -or $Reset) { "--build" } else { "" }
- Write-Info "构建并启动容器(首次构建约 5-10 分钟)..."
- Invoke-Expression "$($script:ComposeCmd) --env-file `"$EnvFile`" up -d $buildArg"
- }
- # ── 等待健康检查 ─────────────────────────────────────────────
- function Wait-ForHealth {
- Write-Host -NoNewline "等待服务就绪"
- $waited = 0
- do {
- Start-Sleep -Seconds 2
- $waited += 2
- Write-Host -NoNewline "."
- if ($waited -gt 120) {
- Write-Host ""
- Write-Err "服务启动超时(120s)"
- Write-Host "查看日志: docker logs lambdagentpaas"
- exit 1
- }
- try {
- $resp = Invoke-WebRequest -Uri "$AppUrl/health" -UseBasicParsing -TimeoutSec 3
- if ($resp.StatusCode -eq 200) { break }
- } catch {}
- } while ($true)
- Write-Host ""
- }
- # ── 打印成功信息 ─────────────────────────────────────────────
- function Print-Success {
- Write-Host ""
- Write-Host "╔══════════════════════════════════════════════╗" -ForegroundColor Green
- Write-Host "║ 🎉 LambdaAgentPaaS 已成功启动! ║" -ForegroundColor Green
- Write-Host "╠══════════════════════════════════════════════╣" -ForegroundColor Green
- Write-Host "║ Web 界面: $AppUrl ║" -ForegroundColor Green
- Write-Host "║ API 文档: $AppUrl/docs ║" -ForegroundColor Green
- Write-Host "╠══════════════════════════════════════════════╣" -ForegroundColor Green
- Write-Host "║ 数据目录: $DataDir" -ForegroundColor Green
- Write-Host "║ 配置文件: $EnvFile" -ForegroundColor Green
- Write-Host "╠══════════════════════════════════════════════╣" -ForegroundColor Green
- Write-Host "║ 停止服务: deploy\stop.bat ║" -ForegroundColor Green
- Write-Host "║ 查看日志: docker logs -f lambdagentpaas ║" -ForegroundColor Green
- Write-Host "╚══════════════════════════════════════════════╝" -ForegroundColor Green
- Write-Host ""
- }
- # ── 主流程 ───────────────────────────────────────────────────
- Write-Header "LambdaAgentPaaS 启动器 (Windows)"
- Check-Docker
- Init-DataDir
- Init-Env
- Load-EnvFile
- Check-ApiKeys
- Start-Services
- Wait-ForHealth
- Print-Success
- # 自动打开浏览器
- Start-Process $AppUrl
|