485 lines
23 KiB
Markdown
485 lines
23 KiB
Markdown
# FLNXI 素材库部署说明
|
||
|
||
本文档是当前主应用部署入口,合并了原来的快速部署、部署前检查清单和完整部署说明。
|
||
|
||
先说结论:
|
||
|
||
- 客户或私有化交付默认按 `NAS(网络存储)` / `Linux(服务器系统)` 现场参数部署。
|
||
- 固定服务器、固定端口、固定 Registry 地址只属于内部维护示例,不是客户默认交付口径。
|
||
- 客户交付必须显式固定完整 `APP_IMAGE`,例如 `registry.example.com/flnxi/material/flnxi-material:1.0.1`;不要把 `latest` 当成客户部署依据。
|
||
- `deploy-registry.ps1` 不再默认指向任何测试服务器,发布和远程部署必须显式传入 `-RegistryHost`,远程部署还必须显式传入 `-Server`。
|
||
- 不同品牌 NAS 或客户自有 Linux 服务器交付前,先看 `docs/deployment/多品牌 NAS 与 Linux 交付差异清单.md`。
|
||
|
||
## 1. 当前部署形态
|
||
|
||
主应用生产编排文件:
|
||
|
||
```bash
|
||
docker-compose.prod.yml
|
||
```
|
||
|
||
当前会拉起:
|
||
|
||
- `postgres`:PostgreSQL 数据库
|
||
- `minio`:MinIO 对象存储
|
||
- `minio-init`:初始化对象存储桶
|
||
- `app`:FLNXI 素材库主应用
|
||
|
||
当前主应用镜像以 Registry 发布链路为准,实际部署时可通过 `.env` 中的 `APP_IMAGE`、`POSTGRES_IMAGE`、`MINIO_IMAGE`、`MINIO_MC_IMAGE` 覆盖。容器名、卷名、网络名和端口也支持用 `.env` 覆盖,下面命令中的 `flnxi-material` 和 `4320` 都只是默认值。
|
||
|
||
`APP_IMAGE` 是生产启动必填项。这样做是为了让客户现场明确运行哪个版本,避免安装或升级时误拉旧仓库、旧测试镜像或 `latest`。
|
||
|
||
根目录 `docker-compose.yml` 是本地/历史维护入口,不是客户正式安装入口。客户交付、NAS 和 Linux 私有化部署统一以 `docker-compose.prod.yml + .env` 为准。
|
||
|
||
当前不会由该 Compose 文件直接拉起:
|
||
|
||
- Nginx / Traefik 等反向代理
|
||
- 独立 `license-server`
|
||
- Node 版或 Go 版安装 Agent
|
||
|
||
这些组件根据交付场景单独部署或由安装 Agent 编排。
|
||
|
||
独立许可证服务的默认编排在 `license-server/docker-compose.yml`。该编排会由 Nginx 对外暴露 `9527`,再反代到内部 `license-server:3000`;应用容器不再直接暴露宿主机端口。这样登录和 API 限流配置会进入默认链路,避免验证服务器在低配置机器上被暴力请求直接打到 Next 服务。
|
||
|
||
## 2. 部署前准备
|
||
|
||
### 2.1 机器条件
|
||
|
||
建议最低条件:
|
||
|
||
- CPU:4 核及以上
|
||
- 内存:8GB 及以上
|
||
- 磁盘:100GB 可用空间
|
||
- 系统:Ubuntu 22.04 LTS、群晖 DSM、飞牛 fnOS 或其他支持 Docker 的 Linux 环境
|
||
- Docker:Docker 24+ 和 Docker Compose V2
|
||
|
||
当前主线安装命令按 Docker Compose 验证。Podman / 图形化容器套件属于目标兼容方向,但不同 NAS 的网络、卷权限和健康检查差异很大,客户交付前必须单独实机验证,不能直接把本文的 Docker 命令等同为 Podman 已完整支持。
|
||
|
||
### 2.2 必填环境变量
|
||
|
||
部署前至少准备:
|
||
|
||
```env
|
||
POSTGRES_PASSWORD=<generate-a-strong-random-password>
|
||
MINIO_ROOT_USER=<generate-a-storage-admin-user>
|
||
MINIO_ROOT_PASSWORD=<generate-a-strong-random-password>
|
||
APP_IMAGE=registry.example.com/flnxi/material/flnxi-material:1.0.1
|
||
SERVER_IP=192.168.x.x
|
||
APP_PUBLIC_URL=http://192.168.x.x:4320
|
||
NEXTAUTH_URL=http://192.168.x.x:4320
|
||
NEXTAUTH_SECRET=<generate-a-strong-random-secret>
|
||
S3_BUCKET=flnxi-materials
|
||
LICENSE_SERVER_URL=https://your-license-server.example.com
|
||
LICENSE_PROJECT_CODE=flnxi-sucai
|
||
LICENSE_REQUEST_SIGNING_SECRET=<generate-a-shared-license-request-secret>
|
||
LICENSE_PUBLIC_KEY=<license-server-rsa-public-key>
|
||
LOCAL_ENCRYPTION_KEY=<generate-a-32-char-or-longer-local-key>
|
||
MAX_UPLOAD_FILE_SIZE_BYTES=10737418240
|
||
MAX_UPLOAD_TOTAL_FILE_SIZE_BYTES=10737418240
|
||
MAX_UPLOAD_FIELD_SIZE_BYTES=2097152
|
||
```
|
||
|
||
说明:
|
||
|
||
- `SERVER_IP` 必须是用户浏览器能访问到的 NAS / 服务器地址。
|
||
- `APP_PUBLIC_URL` 必须和最终访问入口一致,用于生成公开访问、分享和回调相关地址。
|
||
- `NEXTAUTH_URL` 必须和最终访问入口一致。
|
||
- `APP_IMAGE` 必须写完整镜像地址和版本号,不要只写 `latest`。
|
||
- `POSTGRES_IMAGE`、`MINIO_IMAGE`、`MINIO_MC_IMAGE` 建议同样固定版本;离线或受控网络交付时,应写成私有 Registry 里的固定版本镜像。
|
||
- `LICENSE_PROJECT_CODE` 必须和 `license-server` 中项目表的 `projects.code` 一致。
|
||
- `LICENSE_REQUEST_SIGNING_SECRET` 必须和 `license-server` 的同名变量一致,至少 32 字符,用于主应用到验证服务器的请求签名。
|
||
- `LICENSE_PUBLIC_KEY` 是许可证服务签发许可证时使用的 RSA 公钥,主应用靠它确认许可证没有被伪造。
|
||
- `LOCAL_ENCRYPTION_KEY` 用于主应用本地加密保存许可证缓存,至少 32 字符,不能使用示例值。
|
||
- `MAX_UPLOAD_FILE_SIZE_BYTES` 是单个素材文件上限;`MAX_UPLOAD_TOTAL_FILE_SIZE_BYTES` 是一次上传请求总上限;`MAX_UPLOAD_FIELD_SIZE_BYTES` 是表单文字字段总上限。示例值分别是 10GB、10GB、2MB,低配 NAS 可按客户机器内存和磁盘调小。
|
||
- 不要把真实密码、许可证地址、对象存储密钥写入 Git。
|
||
|
||
数据库有两种模式:
|
||
|
||
- 内置 PostgreSQL:`DATABASE_URL` 留空或不写,由 `docker-compose.prod.yml` 按 `POSTGRES_USER`、`POSTGRES_PASSWORD`、`POSTGRES_DB` 自动拼接到 `postgres` 服务。
|
||
- 外部 PostgreSQL:才填写真实 `DATABASE_URL`,例如 `postgresql://flnxi:<password>@192.168.1.10:5432/flnxi?sslmode=disable`。
|
||
|
||
对象存储也有两种模式:
|
||
|
||
- 内置 MinIO:`S3_ENDPOINT=http://minio:9000`,`S3_ACCESS_KEY_ID` / `S3_SECRET_ACCESS_KEY` 可不填,Compose 会使用 `MINIO_ROOT_USER` / `MINIO_ROOT_PASSWORD`。`S3_PUBLIC_DOMAIN` 必须写成用户浏览器能访问的地址,例如 `http://192.168.1.20:9000/flnxi-materials`。
|
||
- 外部 S3 / 外部 MinIO:需要填写真实 `S3_ENDPOINT`、`S3_ACCESS_KEY_ID`、`S3_SECRET_ACCESS_KEY`、`S3_BUCKET`、`S3_PUBLIC_DOMAIN`,并确认 bucket 已存在或当前账号有创建和读写权限。
|
||
|
||
NAS 或 Linux 服务器上建议提前准备挂载目录:
|
||
|
||
```bash
|
||
mkdir -p uploads data
|
||
chown -R 1001:1001 uploads data
|
||
chmod 775 uploads data
|
||
```
|
||
|
||
如果客户系统启用了更严格的用户权限,需让运行主应用容器的用户可以写入这两个目录;当前镜像内应用用户通常按 UID `1001` 理解。飞牛 / NAS 场景里,第一次手工创建目录如果是 root 所有权,单纯 `chmod 775` 可能还是不够,优先把目录属主改成 `1001:1001`。最简单的验收标准是:容器启动后能上传素材,`uploads/` 和 `data/` 没有持续出现权限拒绝日志。
|
||
|
||
### 2.3 HTTP Registry 前置检查
|
||
|
||
如果 Registry 使用 `http://`,本机 Docker 和目标机器 Docker 都要先允许这个 Registry。否则会出现 `HTTP response to HTTPS client`,表现为登录、推送或拉取镜像失败。
|
||
|
||
Linux 目标机常见配置:
|
||
|
||
```json
|
||
{
|
||
"insecure-registries": ["registry.example.com:5000"]
|
||
}
|
||
```
|
||
|
||
配置位置通常是 `/etc/docker/daemon.json`。改完后重启 Docker:
|
||
|
||
```bash
|
||
sudo systemctl restart docker
|
||
docker info | grep -A 5 "Insecure Registries"
|
||
```
|
||
|
||
Docker Desktop 需要在设置里的 Docker Engine 配置同样的 `insecure-registries`,保存并重启 Docker。
|
||
|
||
## 3. 标准部署步骤
|
||
|
||
### 3.1 区分首装和升级
|
||
|
||
当前交付链路分三段看,不能混成一个命令:
|
||
|
||
- 发布方构建和推送镜像:使用 `deploy-registry.ps1` 的发布动作,产出固定版本镜像。
|
||
- 客户首次安装:在目标机器准备部署目录、`docker-compose.prod.yml`、`.env`、数据卷和固定版本镜像,然后启动 Compose。
|
||
- 已有客户升级:使用 `deploy-registry.ps1 -Action DeployApp` 写入新 `APP_IMAGE`,并执行备份、拉取、迁移、健康检查和失败回滚。
|
||
|
||
`deploy-registry.ps1 -Action DeployApp` 默认假设远端已经有部署目录、生产 Compose 和 `.env`,它是升级/远程更新入口,不是单独完整的首装向导。
|
||
|
||
### 3.2 准备环境文件
|
||
|
||
在目标机器部署目录准备 `.env`:
|
||
|
||
```bash
|
||
cp .env.example .env
|
||
```
|
||
|
||
再按实际环境补齐数据库、MinIO、NextAuth、许可证和访问地址。首装使用内置 PostgreSQL 时,不要给 `DATABASE_URL` 填占位连接串;外部 PostgreSQL 才填写真实连接串。
|
||
|
||
### 3.3 启动服务
|
||
|
||
正式客户交付先通过 `deploy-registry.ps1` 完成版本化镜像发布,并把远端 `.env` 里的 `APP_IMAGE` 写到目标版本,再执行下面的启动命令。
|
||
|
||
```bash
|
||
docker compose -f docker-compose.prod.yml up -d
|
||
```
|
||
|
||
生产 Compose 只读取 `APP_IMAGE`,不包含 `build:`。如果需要重新构建镜像,应在发布方机器使用 `deploy-registry.ps1` 或内部构建脚本先生成版本镜像,再更新 `.env`。
|
||
|
||
离线或受控网络交付时,启动前还要确认 `APP_IMAGE`、`POSTGRES_IMAGE`、`MINIO_IMAGE`、`MINIO_MC_IMAGE` 都已经在目标机器 Docker 或客户私有 Registry 中存在。否则 `docker compose up -d` 会因为无法拉取镜像而失败。
|
||
|
||
### 3.4 初始化数据库
|
||
|
||
主应用容器入口脚本 `scripts/docker-entrypoint.sh` 会在启动时自动执行:
|
||
|
||
```bash
|
||
npx prisma migrate deploy
|
||
```
|
||
|
||
所以常规部署不需要手动再跑一次数据库迁移。
|
||
|
||
如果历史模板数据需要补齐,或自动迁移失败后要人工补救,再按实际容器名执行:
|
||
|
||
```bash
|
||
docker exec <APP_CONTAINER_NAME> npm run migrate:template-data
|
||
docker exec <APP_CONTAINER_NAME> npm run verify:template-data
|
||
```
|
||
|
||
默认容器名是 `flnxi-material`;如果 `.env` 配了 `APP_CONTAINER_NAME`,以实际值为准。
|
||
|
||
如是全新环境,继续按 `docs/初次部署与出厂设置指南.md` 走系统初始化流程。
|
||
|
||
### 3.5 验证服务
|
||
|
||
```bash
|
||
docker compose -f docker-compose.prod.yml ps
|
||
curl http://<SERVER_IP>:4320/api/health
|
||
docker logs flnxi-material --tail 100
|
||
```
|
||
|
||
`/api/health` 返回 `200` 表示应用启动检查已通过;如果返回 `503`,先查看 `docker logs flnxi-material --tail 100`,通常是数据库连接、迁移或内置模板初始化未完成。
|
||
|
||
如果 `.env` 覆盖了 `APP_PORT` 或 `APP_CONTAINER_NAME`,验证命令也要同步替换成实际端口和容器名。
|
||
|
||
页面验证:
|
||
|
||
- 登录页:`http://<SERVER_IP>:4320/login`
|
||
- 首页:`http://<SERVER_IP>:4320`
|
||
- 管理后台:`http://<SERVER_IP>:4320/admin`
|
||
- 模板管理:在 `http://<SERVER_IP>:4320/admin` 后台内打开;当前没有独立的 `/admin/templates` 路由
|
||
|
||
## 4. 版本化 Registry 发布
|
||
|
||
当前仓库的主发布脚本是 `deploy-registry.ps1`,用于构建、推送和远程更新主应用、Agent 以及运行时镜像。它默认会把版本镜像写入远端 `.env`,客户升级不要再回退到默认 `latest`。
|
||
|
||
`DeployApp` 远程部署现在默认包含第一轮升级保护:
|
||
|
||
- 升级前在远端创建 `backups/deploy-时间戳/`,保存升级前 `.env`。
|
||
- 如果远端 PostgreSQL 是当前 Compose 管理的 `postgres` 服务,会先执行 `pg_dump` 备份;如果使用外部数据库,会提示需要确认外部备份。
|
||
- 如果远端 MinIO 是当前 Compose 管理的 `minio` 服务,会先把 `MINIO_VOLUME_NAME` 对应的数据卷打包备份;如果使用外部 S3 / 外部 MinIO,会在备份目录写入提示文件,要求按客户现场方案单独备份对象存储。
|
||
- 备份目录会生成 `RESTORE_PLAN.txt`,把本次 `.env`、PostgreSQL、MinIO 备份文件和 L1/L2/L3 恢复命令列出来,便于升级失败时按影响范围恢复。
|
||
- 部署失败时默认尝试恢复升级前 `.env`,并按旧运行镜像或旧 `APP_IMAGE` 重建应用容器。
|
||
- 部署后会在远端校验应用容器实际运行镜像、镜像内 `VERSION.txt` 和 Prisma 迁移状态,然后再做外部 `/api/health` 检查。
|
||
|
||
只有在已有其它备份和回滚体系时,才考虑使用 `-NoRemoteDbBackup`、`-NoRemoteObjectStorageBackup` 或 `-NoRollback`。离线客户现场如果没有 `busybox:1.36`,需要先把该 helper 镜像放到目标机,或通过 `-RemoteBackupHelperImage` 指定现场已有的小型 Linux 镜像。
|
||
|
||
必须注意:脚本的自动回滚只恢复应用镜像和 `.env`,不自动恢复数据库和对象存储。只要本次升级包含数据库迁移或素材文件结构变化,升级前的数据库备份和对象存储备份就必须保留,并按 `RESTORE_PLAN.txt` 的 L2/L3 步骤由人工确认后恢复。
|
||
|
||
典型用法:
|
||
|
||
```powershell
|
||
$registryPassword = Read-Host 'Registry密码' -AsSecureString
|
||
$sshPassword = Read-Host 'SSH密码' -AsSecureString
|
||
.\deploy-registry.ps1 -Action DeployApp -DeployChannel release -Version 1.0.1 -RegistryHost registry.example.com:5000 -Server 192.168.1.20 -RegistryPassword $registryPassword -Password $sshPassword
|
||
.\deploy-registry.ps1 -Action PublishRelease -Version 1.0.1 -RegistryHost registry.example.com:5000 -RegistryPassword $registryPassword
|
||
.\deploy-registry.ps1 -Action PublishAgent -Version 1.0.1 -RegistryHost registry.example.com:5000 -RegistryPassword $registryPassword
|
||
.\deploy-registry.ps1 -Action SyncRuntime -RegistryHost registry.example.com:5000 -RegistryPassword $registryPassword
|
||
```
|
||
|
||
说明:
|
||
|
||
- 客户升级和内部发布优先按版本 tag 走,不要把 `latest` 当成客户部署依据。
|
||
- 客户现场部署使用 `-DeployChannel release -Version x.x.x`;测试通道只用于内部验证,必须显式传 `-DeployChannel test`。
|
||
- `DeployApp` 远程部署时默认会更新远端 `.env` 的 `APP_IMAGE`、访问地址和运行时镜像;只有临时验证时才使用 `-NoUpdateRemoteEnv`。
|
||
- `DeployApp` 默认会做远端 `.env` 备份、Compose PostgreSQL 备份、Compose MinIO 备份、恢复分级说明、失败自动回滚、运行镜像校验、版本文件校验和 Prisma 迁移状态校验。
|
||
- 旧的 `deploy-new-fixed.ps1` 仍可作为内部维护参考,但不再作为当前主线部署入口。
|
||
- 如果要做远程更新,先确认 `Registry`、SSH、`.env` 和目标机器都属于当前维护环境。
|
||
|
||
### 4.1 镜像体积基线
|
||
|
||
发布前可以对主应用镜像做一次体积和分层记录:
|
||
|
||
```powershell
|
||
.\scripts\measure-image-size.ps1 `
|
||
-Image "registry.example.com/flnxi/material/flnxi-material:1.0.1" `
|
||
-OutputPath ".\reports\image-size-1.0.1.md"
|
||
```
|
||
|
||
这个脚本不会改镜像,只会读取 Docker 本地镜像信息,列出总大小、层数和最大的若干层。后续做镜像瘦身时,先用这个报告确认是 `ffmpeg`、字体、`canvas`、`node_modules` 还是 Prisma 迁移工具占用更大,再决定是否拆成可选能力或独立迁移镜像。
|
||
|
||
## 5. 部署前检查清单
|
||
|
||
- [ ] 已确认目标机器品牌、系统和 Docker Compose 支持情况;如使用 Podman,已单独实机验证
|
||
- [ ] 已确认端口、域名、证书、反向代理方案
|
||
- [ ] 已确认数据目录、对象存储目录和备份位置
|
||
- [ ] 已确认升级失败时使用 L1 应用回滚、L2 数据库恢复还是 L3 数据库+素材恢复
|
||
- [ ] `.env` 已填写真实环境变量;内置 PostgreSQL 模式下 `DATABASE_URL` 没有错误占位值
|
||
- [ ] `APP_IMAGE` 已固定到完整版本镜像,不使用 `latest`
|
||
- [ ] 如果 Registry 是 HTTP,本机和目标机 Docker 都已配置 `insecure-registries`
|
||
- [ ] `NEXTAUTH_URL` 与最终访问地址一致
|
||
- [ ] `S3_BUCKET`、`S3_PUBLIC_DOMAIN` 口径正确
|
||
- [ ] `LICENSE_SERVER_URL` 和 `LICENSE_PROJECT_CODE` 已确认
|
||
- [ ] `LICENSE_REQUEST_SIGNING_SECRET` 已配置且与许可证服务一致
|
||
- [ ] `LICENSE_PUBLIC_KEY`、`LOCAL_ENCRYPTION_KEY` 已配置为真实值
|
||
- [ ] `uploads/`、`data/` 目录对应用容器可写
|
||
- [ ] 已执行与本次改动相关的测试或命令
|
||
- [ ] 涉及数据库变更时已有备份和回滚方案
|
||
|
||
## 6. 部署后冒烟测试
|
||
|
||
启动前可以先做一轮不启动容器的安装前检查:
|
||
|
||
```powershell
|
||
.\scripts\smoke-install.ps1 -ProjectDir "D:\deploy\flnxi" -PreflightOnly
|
||
```
|
||
|
||
如果是新目录,还希望脚本顺手创建 `uploads/` 和 `data/`,可以加:
|
||
|
||
```powershell
|
||
.\scripts\smoke-install.ps1 -ProjectDir "D:\deploy\flnxi" -PreflightOnly -PrepareDirectories
|
||
```
|
||
|
||
这一步会提前拦截 `.env` 示例值、`latest` 镜像、缺失数据目录和明显错误的访问地址,避免等容器启动失败后再排查。
|
||
|
||
首装后优先使用脚本做基础验收:
|
||
|
||
```powershell
|
||
.\scripts\smoke-install.ps1 -ProjectDir "D:\deploy\flnxi" -Start
|
||
```
|
||
|
||
如果服务已经由 NAS 图形界面或其他编排入口启动,可以去掉 `-Start`,只做检查:
|
||
|
||
```powershell
|
||
.\scripts\smoke-install.ps1 -ProjectDir "D:\deploy\flnxi"
|
||
```
|
||
|
||
该脚本会先做安装前检查,再检查 Compose 配置、容器状态、应用运行镜像、镜像内版本文件、Prisma 迁移状态、MinIO bucket 和 `/api/health`。如果客户使用外部对象存储,加 `-SkipObjectStorageCheck`,对象存储验收按客户现场方案单独执行。
|
||
|
||
人工验收命令仍保留如下:
|
||
|
||
- [ ] `/api/health` 正常
|
||
- [ ] 登录 / 退出正常
|
||
- [ ] 首次初始化或激活流程正常
|
||
- [ ] 首页素材列表可加载
|
||
- [ ] 素材上传、预览、下载正常
|
||
- [ ] 后台模板管理可打开
|
||
- [ ] 系统设置可读取和保存
|
||
- [ ] 许可证状态显示正确
|
||
- [ ] 容器日志没有持续错误
|
||
|
||
## 7. 数据备份与回滚
|
||
|
||
`deploy-registry.ps1 -Action DeployApp` 会默认做一轮升级前备份和失败回滚。下面命令主要用于人工兜底、外部数据库场景或单独恢复演练。
|
||
|
||
### 7.1 一键备份
|
||
|
||
首选脚本:
|
||
|
||
```powershell
|
||
.\scripts\backup-restore.ps1 -ProjectDir "D:\deploy\flnxi" -Action Backup
|
||
```
|
||
|
||
默认备份内容:
|
||
|
||
- `.env`
|
||
- `docker-compose.prod.yml`
|
||
- `VERSION.txt`,如果部署目录里存在
|
||
- `compose-config.txt`、`compose-ps.txt`、`docker-images.txt`
|
||
- Compose 管理的 PostgreSQL:`postgres.sql`
|
||
- Compose 管理的 MinIO 数据卷:`minio-data.tar.gz`
|
||
- `manifest.json`:记录备份时间、应用镜像、访问地址、服务名等关键信息
|
||
|
||
`DeployApp` 升级时生成的 `backups/deploy-时间戳/RESTORE_PLAN.txt` 是升级恢复指引;`backup-restore.ps1 -Action Backup` 生成的 `flnxi-backup-时间戳/manifest.json` 是完整备份包记录。两者用途不同,客户升级失败时优先看当次升级目录里的 `RESTORE_PLAN.txt`。
|
||
|
||
如果 `DATABASE_URL` 指向外部 PostgreSQL,脚本不会假装自动备份,会在备份目录写入 `EXTERNAL_DATABASE_BACKUP_REQUIRED.txt`,客户现场必须按外部数据库方案单独备份。
|
||
|
||
如果对象存储是外部 S3 / 外部 MinIO,或现场已有独立对象存储快照,可加:
|
||
|
||
```powershell
|
||
.\scripts\backup-restore.ps1 -ProjectDir "D:\deploy\flnxi" -Action Backup -SkipObjectStorageBackup
|
||
```
|
||
|
||
内置 MinIO 备份/恢复默认使用 `busybox:1.36` 作为 helper 镜像。离线客户现场需要提前把该镜像放进 Docker,或通过 `-HelperImage` 指定现场已有的 Linux 工具镜像。
|
||
|
||
### 7.2 一键验收
|
||
|
||
```powershell
|
||
.\scripts\backup-restore.ps1 -ProjectDir "D:\deploy\flnxi" -Action Verify
|
||
```
|
||
|
||
该动作会检查 Compose 配置、容器状态和 `/api/health`,适合备份前、恢复后、升级后快速确认系统是否可用。
|
||
|
||
### 7.3 一键恢复
|
||
|
||
恢复会覆盖客户数据,必须停写入并确认备份来源正确。脚本要求输入固定确认短语,避免误操作:
|
||
|
||
```powershell
|
||
.\scripts\backup-restore.ps1 `
|
||
-ProjectDir "D:\deploy\flnxi" `
|
||
-Action Restore `
|
||
-BackupPath "D:\deploy\flnxi\backups\flnxi-backup-YYYYMMDD-HHMMSS" `
|
||
-ConfirmRestore RESTORE_FLNXI_DATA
|
||
```
|
||
|
||
说明:
|
||
|
||
- 默认恢复 `postgres.sql` 和 `minio-data.tar.gz`,然后启动服务并执行健康验收。
|
||
- 如果只恢复数据库、不恢复对象存储,加 `-SkipObjectStorageRestore`。
|
||
- 如果需要把备份包中的 `.env` 一起恢复,加 `-RestoreEnv`;脚本会先把当前 `.env` 另存为 `.env.before-restore-时间戳`。
|
||
- 外部数据库和外部对象存储不受该脚本自动恢复,必须按客户现场备份方案操作。
|
||
|
||
### 7.4 手动备份数据库
|
||
|
||
```bash
|
||
docker exec flnxi-postgres pg_dump \
|
||
-U postgres \
|
||
-d flnxi \
|
||
-F c \
|
||
-f /tmp/flnxi-backup-$(date +%Y%m%d-%H%M%S).dump
|
||
```
|
||
|
||
再把备份文件复制到宿主机或外部备份位置。外部数据库不受 Compose 脚本管理,必须按客户现场数据库方案单独备份。
|
||
|
||
### 7.5 手动回滚应用
|
||
|
||
如使用镜像部署,回滚到上一镜像版本时,直接改完整 `APP_IMAGE`。不要只改 `IMAGE_TAG`,因为完整 `APP_IMAGE` 的优先级更高。
|
||
|
||
```bash
|
||
docker compose -f docker-compose.prod.yml down
|
||
cp .env .env.rollback-$(date +%Y%m%d-%H%M%S)
|
||
sed -i 's#^APP_IMAGE=.*#APP_IMAGE=registry.example.com/flnxi/material/flnxi-material:<previous-version>#' .env
|
||
docker compose -f docker-compose.prod.yml pull app
|
||
docker compose -f docker-compose.prod.yml up -d app
|
||
curl http://<SERVER_IP>:4320/api/health
|
||
```
|
||
|
||
回滚后 `/api/health` 仍必须返回 `200` 才算应用恢复可用。
|
||
|
||
回滚前先确认数据库是否需要同时回滚。只回滚应用镜像不等于回滚数据库结构;如果本次升级包含数据库迁移,必须先确认备份和恢复路径。
|
||
|
||
### 7.6 手动恢复数据库
|
||
|
||
恢复前必须确认已停止会写入数据库的应用容器,并确认备份文件正确。下面给两种常见方式,二选一即可。
|
||
|
||
```bash
|
||
docker cp ./flnxi-backup-YYYYMMDD-HHMMSS.dump flnxi-postgres:/tmp/flnxi-restore.dump
|
||
docker exec flnxi-postgres pg_restore \
|
||
-U postgres \
|
||
-d flnxi \
|
||
-c \
|
||
/tmp/flnxi-restore.dump
|
||
```
|
||
|
||
或者直接从宿主机标准输入恢复:
|
||
|
||
```bash
|
||
docker exec -i flnxi-postgres pg_restore \
|
||
-U postgres \
|
||
-d flnxi \
|
||
-c \
|
||
< ./flnxi-backup-YYYYMMDD-HHMMSS.dump
|
||
```
|
||
|
||
## 8. 常见问题
|
||
|
||
### 应用访问不到
|
||
|
||
优先检查:
|
||
|
||
- `docker compose -f docker-compose.prod.yml ps`
|
||
- `APP_PORT` 是否和访问端口一致
|
||
- `SERVER_IP` 和 `NEXTAUTH_URL` 是否填写成浏览器可访问地址
|
||
- 防火墙是否放通端口
|
||
|
||
### MinIO 预览或下载异常
|
||
|
||
优先检查:
|
||
|
||
- `S3_BUCKET`
|
||
- `MINIO_ROOT_USER`
|
||
- `MINIO_ROOT_PASSWORD`
|
||
- `S3_PUBLIC_DOMAIN`
|
||
- MinIO 控制台是否能看到桶和对象
|
||
- `S3_SET_ACL` 是否仍为默认 `0`。私有化交付默认不公开素材桶;只有兼容旧公开对象模式时才允许显式改成 `1`。
|
||
- 当前生产 Compose 的 `minio-init` 会默认执行 `mc anonymous set none`,用于关闭 MinIO 桶匿名下载。如果客户历史环境曾经公开过桶,升级后应重跑 `minio-init` 或手动执行同等命令确认桶已恢复私有。
|
||
- 外部 S3 或历史环境可能存在旧 bucket policy、旧对象级 ACL 或历史公开链接,这些不一定会被当前 `minio-init` 自动收回,升级前后要单独做只读审计。
|
||
|
||
### 许可证异常
|
||
|
||
优先检查:
|
||
|
||
- `LICENSE_SERVER_URL`
|
||
- `LICENSE_PROJECT_CODE`
|
||
- `LICENSE_REQUEST_SIGNING_SECRET` 是否与许可证服务一致
|
||
- 许可证服务是否存在对应项目编码
|
||
- 主应用 `/api/license/check`、`/api/license/verify` 响应
|
||
- 如果独立部署 `license-server/docker-compose.yml`,确认对外访问的是 Nginx 暴露的 `9527`,不是容器内部 `3000`。
|
||
- 如果请求返回 `429`,优先检查 Nginx 限流是否被触发,再看是否存在脚本重试、暴力激活或心跳频率异常。
|
||
|
||
### 数据迁移失败
|
||
|
||
优先查看:
|
||
|
||
```bash
|
||
docker logs flnxi-material --tail 200
|
||
docker exec flnxi-material npx prisma validate
|
||
docker exec flnxi-material npm run verify:template-data
|
||
```
|
||
|
||
## 9. 相关文档
|
||
|
||
- `docs/初次部署与出厂设置指南.md`
|
||
- `docs/deployment/多品牌 NAS 与 Linux 交付差异清单.md`
|
||
- `docs/许可证服务接入说明.md`
|
||
- `scripts/README.md`
|