diff --git a/README.md b/README.md index fdffaa9..fde2101 100644 --- a/README.md +++ b/README.md @@ -205,6 +205,7 @@ docker compose -f docker-compose.prod.yml up -d 内部维护环境仍保留: - `deploy-registry.ps1` +- `scripts/customer-install.ps1` - `scripts/smoke-install.ps1` - `scripts/backup-restore.ps1` - `scripts/measure-image-size.ps1` @@ -212,7 +213,7 @@ docker compose -f docker-compose.prod.yml up -d - `发布管理.ps1` - `license-server/deploy.ps1` -其中 `scripts/smoke-install.ps1` 用于首装后的基础验收,`scripts/backup-restore.ps1` 用于客户环境备份、恢复和恢复后验收,`scripts/measure-image-size.ps1` 用于发布前记录镜像体积和分层。其它脚本执行前必须先读内容和参数,不应把内部固定服务器或固定镜像仓库当成客户默认交付配置。客户交付时要显式写入版本化 `APP_IMAGE` / `IMAGE_TAG`,`latest` 只保留给内部测试或兼容场景。当前新 Registry 发布脚本是主线,旧远程部署脚本只作历史或内部维护参考。AI、钉钉、内网穿透等可选能力依赖真实外部服务和密钥,不能只凭页面入口当成客户验收已完成。 +其中 `scripts/customer-install.ps1` 是客户首装分步骤入口,内部调用 `scripts/smoke-install.ps1` 做预检、启动和验收;`scripts/backup-restore.ps1` 用于客户环境备份、恢复和恢复后验收,`scripts/measure-image-size.ps1` 用于发布前记录镜像体积和分层。其它脚本执行前必须先读内容和参数,不应把内部固定服务器或固定镜像仓库当成客户默认交付配置。客户交付时要显式写入版本化 `APP_IMAGE` / `IMAGE_TAG`,`latest` 只保留给内部测试或兼容场景。当前新 Registry 发布脚本是主线,旧远程部署脚本只作历史或内部维护参考。AI、钉钉、内网穿透等可选能力依赖真实外部服务和密钥,不能只凭页面入口当成客户验收已完成。 ## 10. 文档入口 diff --git a/docs/deployment/部署说明.md b/docs/deployment/部署说明.md index b260258..0146723 100644 --- a/docs/deployment/部署说明.md +++ b/docs/deployment/部署说明.md @@ -283,6 +283,20 @@ $sshPassword = Read-Host 'SSH密码' -AsSecureString .\scripts\smoke-install.ps1 -ProjectDir "D:\deploy\flnxi" -PreflightOnly ``` +如果希望给实施人员一个更像向导的入口,可以先只看步骤: + +```powershell +.\scripts\customer-install.ps1 -ProjectDir "D:\deploy\flnxi" -PlanOnly +``` + +确认 `.env`、镜像和数据目录都准备好后,让脚本按步骤预检、启动并验收: + +```powershell +.\scripts\customer-install.ps1 -ProjectDir "D:\deploy\flnxi" -PrepareDirectories -Start +``` + +`customer-install.ps1` 只是对 `smoke-install.ps1` 的分步骤包装,不替代 `docker-compose.prod.yml`,也不把 Agent 当成唯一安装入口。 + 如果是新目录,还希望脚本顺手创建 `uploads/` 和 `data/`,可以加: ```powershell diff --git a/flnxi-agent-go/install.sh b/flnxi-agent-go/install.sh index a4271cb..c42de27 100644 --- a/flnxi-agent-go/install.sh +++ b/flnxi-agent-go/install.sh @@ -1,6 +1,7 @@ #!/bin/bash # -# FLNXI 一键部署脚本 +# FLNXI Agent 安装脚本 +# 只安装 Agent,不等于完整安装素材库。 # 用法: curl -sSL https://install.flnxi.com | bash # # 或者带参数: diff --git a/flnxi-agent/README.md b/flnxi-agent/README.md index 65bb73b..fc55807 100644 --- a/flnxi-agent/README.md +++ b/flnxi-agent/README.md @@ -6,9 +6,10 @@ FLNXI 素材系统历史 Node 版安装助手。 正式客户安装、升级和发布不要照抄本目录的镜像名或命令。当前项目主线应以 `deploy-registry.ps1`、`docker-compose.prod.yml` 和明确版本号的镜像为准。 -## 功能 +## 历史能力 -- 🚀 一键安装素材系统及所有依赖 +- 下面是 Node 版 Agent 旧设计能力,不作为新客户安装承诺。 +- 一键安装素材系统及所有依赖 - 📊 实时安装进度显示 - 🔄 系统更新和回滚 - 📈 系统状态监控 diff --git a/scripts/README.md b/scripts/README.md index d88a2be..c694725 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -39,6 +39,8 @@ npm run verify:template-data 生产构建后的服务端混淆处理。客户交付镜像通过 `Dockerfile` 执行 `npm run build:prod` 时会自动调用;混淆依赖或配置缺失会直接失败,不能静默跳过。 - `docker-entrypoint.sh` 主应用容器启动入口 +- `customer-install.ps1` + 客户首装向导入口,按步骤调用 `smoke-install.ps1` 做预检、启动和验收;不替代生产 Compose,也不依赖 Agent - `smoke-install.ps1` 客户首装后的基础验收脚本,可检查 Compose 配置、容器状态、运行镜像、版本文件、迁移状态、MinIO bucket 和 `/api/health` - `backup-restore.ps1` @@ -104,6 +106,20 @@ npx tsx scripts/fix-missing-templates.ts ### 客户首装基础验收 +更推荐给实施人员的向导入口: + +```powershell +.\scripts\customer-install.ps1 -ProjectDir "D:\deploy\flnxi" -PlanOnly +.\scripts\customer-install.ps1 -ProjectDir "D:\deploy\flnxi" -PrepareDirectories -Start +``` + +说明: + +- `-PlanOnly` 只打印四步流程,不启动容器。 +- `-PrepareDirectories` 会创建并测试 `uploads/` 和 `data/`。 +- `-Start` 会执行 `docker compose up -d`;如果已经由 NAS 图形界面启动,可以不传。 +- 这个脚本内部仍调用 `smoke-install.ps1`,不引入第二套安装逻辑。 + ```powershell .\scripts\smoke-install.ps1 -ProjectDir "D:\deploy\flnxi" -PreflightOnly .\scripts\smoke-install.ps1 -ProjectDir "D:\deploy\flnxi" -Start diff --git a/scripts/__tests__/customer-install-script.test.ts b/scripts/__tests__/customer-install-script.test.ts new file mode 100644 index 0000000..97829b5 --- /dev/null +++ b/scripts/__tests__/customer-install-script.test.ts @@ -0,0 +1,31 @@ +import fs from 'fs' +import path from 'path' + +describe('scripts/customer-install.ps1', () => { + const script = fs.readFileSync( + path.join(process.cwd(), 'scripts/customer-install.ps1'), + 'utf8' + ) + + it('是 smoke-install 的分步骤包装,不另造部署入口', () => { + expect(script).toContain('smoke-install.ps1') + expect(script).toContain('docker-compose.prod.yml') + expect(script).toContain('不替代 docker-compose.prod.yml') + }) + + it('支持只看计划、自动创建目录和脚本启动容器', () => { + expect(script).toContain('[switch]$PlanOnly') + expect(script).toContain('[switch]$PrepareDirectories') + expect(script).toContain('[switch]$Start') + expect(script).toContain('-PreflightOnly') + expect(script).toContain('-Start') + }) + + it('把客户验收拆成清楚的四步', () => { + expect(script).toContain('Write-Step 1') + expect(script).toContain('Write-Step 2') + expect(script).toContain('Write-Step 3') + expect(script).toContain('Write-Step 4') + expect(script).toContain('管理员初始化、登录、上传和下载验收') + }) +}) diff --git a/scripts/customer-install.ps1 b/scripts/customer-install.ps1 new file mode 100644 index 0000000..8b55375 --- /dev/null +++ b/scripts/customer-install.ps1 @@ -0,0 +1,102 @@ +# FLNXI 客户首装向导脚本 +# 这是对 smoke-install.ps1 的分步骤包装,不替代 docker-compose.prod.yml。 + +param( + [string]$ProjectDir = ".", + [string]$ComposeFile = "docker-compose.prod.yml", + [string]$EnvFile = ".env", + [switch]$Start, + [switch]$PrepareDirectories, + [switch]$PlanOnly, + [switch]$SkipMigrationStatus, + [switch]$SkipObjectStorageCheck, + [int]$HealthTimeoutSeconds = 120 +) + +Set-StrictMode -Version Latest +$ErrorActionPreference = "Stop" + +function Write-Step { + param([int]$Number, [string]$Message) + Write-Host "" + Write-Host "[$Number/4] $Message" -ForegroundColor Cyan +} + +function Invoke-SmokeInstall { + param([string[]]$ExtraArgs) + + $scriptPath = Join-Path $PSScriptRoot "smoke-install.ps1" + if (-not (Test-Path -LiteralPath $scriptPath -PathType Leaf)) { + throw "找不到 smoke-install.ps1:$scriptPath" + } + + $smokeArgs = @( + "-ProjectDir", $ProjectDir, + "-ComposeFile", $ComposeFile, + "-EnvFile", $EnvFile, + "-HealthTimeoutSeconds", "$HealthTimeoutSeconds" + ) + + if ($SkipMigrationStatus) { + $smokeArgs += "-SkipMigrationStatus" + } + if ($SkipObjectStorageCheck) { + $smokeArgs += "-SkipObjectStorageCheck" + } + + & powershell -ExecutionPolicy Bypass -File $scriptPath @smokeArgs @ExtraArgs + if ($LASTEXITCODE -ne 0) { + throw "安装验收步骤失败,退出码:$LASTEXITCODE" + } +} + +Write-Host "========================================" -ForegroundColor Cyan +Write-Host " FLNXI 客户首装向导" -ForegroundColor Cyan +Write-Host "========================================" -ForegroundColor Cyan +Write-Host "部署目录:$ProjectDir" +Write-Host "Compose:$ComposeFile" +Write-Host "环境文件:$EnvFile" + +Write-Step 1 "检查部署文件和客户现场配置" +Write-Host "会检查 .env、APP_IMAGE、许可证参数、数据目录和常见占位值。" +if ($PrepareDirectories) { + Write-Host "缺少 uploads/data 目录时会自动创建并测试写入。" +} + +if ($PlanOnly) { + Write-Step 2 "准备启动方式" + Write-Host "如果希望脚本启动容器,请重新执行并加 -Start。" + Write-Host "如果已经通过 NAS 图形界面启动,则不加 -Start,脚本只做验收。" + Write-Step 3 "运行首装验收" + Write-Host "验收内容包括 Compose 配置、容器状态、运行镜像、VERSION.txt、/api/health、Prisma 迁移状态和 MinIO bucket。" + Write-Step 4 "查看结果" + Write-Host "所有步骤通过后,浏览器打开 APP_PUBLIC_URL / NEXTAUTH_URL。" + Write-Host "如失败,根据脚本输出先修 .env、镜像、目录权限或容器日志。" + return +} + +$preflightArgs = @("-PreflightOnly") +if ($PrepareDirectories) { + $preflightArgs += "-PrepareDirectories" +} +Invoke-SmokeInstall -ExtraArgs $preflightArgs + +Write-Step 2 "确认容器启动方式" +if ($Start) { + Write-Host "将由脚本执行 docker compose up -d。" +} else { + Write-Host "未传 -Start,默认认为容器已由 NAS 图形界面或其它编排入口启动。" +} + +Write-Step 3 "执行首装启动和验收" +$verifyArgs = @() +if ($Start) { + $verifyArgs += "-Start" +} +if ($PrepareDirectories) { + $verifyArgs += "-PrepareDirectories" +} +Invoke-SmokeInstall -ExtraArgs $verifyArgs + +Write-Step 4 "完成" +Write-Host "首装向导完成。下一步请用浏览器打开 APP_PUBLIC_URL / NEXTAUTH_URL,并完成管理员初始化、登录、上传和下载验收。"