提交 c3417d53 authored 作者: 陈泽健's avatar 陈泽健

docs(deploy): 新增容器化部署Volume挂载优化需求文档和执行计划文档

变更内容:
- 修正 CreateCMD 本地路径 E:\GithubData → E:\github
- 修复 package-lock.json 中依赖的 peer 标记
- 新增部署运维 PRD 需求文档和计划执行文档
- 补充部署方案文档至版本控制
Co-Authored-By: 's avatarClaude <noreply@anthropic.com>
上级 561591ef
@echo off
cd /d E:\GithubData\ubains-module-test\platform-auto-test
cd /d E:\github\ubains-module-test\platform-auto-test
E:\nodejs\claude.cmd --permission-mode bypassPermissions
# 容器化部署优化:Volume 挂载免重建镜像 需求文档
> **文档版本**: v1.0
> **创建日期**: 2026-07-27
> **文档状态**: 初稿待评审
> **负责人**: czj
---
## 一、背景
### 1.1 问题描述
当前 `platform-auto-test` 平台已通过 Docker 容器化部署在服务器 `192.168.5.60` 上,部署配置位于 `deploy/` 目录。但现有部署方式存在以下问题:
1. **代码更新需重建镜像**:Dockerfile 使用 `COPY` 将代码打包进镜像,每次修改 Python/Vue 代码后,必须执行 `docker compose build` 重新构建镜像,构建过程耗时 3-5 分钟
2. **频繁构建影响效率**:开发迭代阶段修改频繁,每次构建浪费大量时间
3. **与另一维护服务冲突风险**:当前代码在 `~/ubains-module-test/` git 目录下,与另一个维护平台(8088 端口)共用同一仓库,存在分支冲突风险
### 1.2 当前部署架构
```
服务器 192.168.5.60
├── ~/ubains-module-test/ ← git 仓库(与另一服务共用)
│ ├── deploy/ ← 部署配置
│ │ ├── docker-compose.yml ← 代码 COPY 进镜像
│ │ ├── Dockerfile.backend ← 代码 COPY 进镜像
│ │ └── Dockerfile.frontend ← 代码 COPY 进镜像
│ └── data/ ← 数据库持久化(空库)
└── /opt/troubleshoot/ ← 另一维护平台(8088 端口,不受影响)
```
### 1.3 目标
1. **独立目录部署**:将本平台部署到独立目录 `/opt/plat-auto-test/`,与另一服务完全隔离
2. **Volume 挂载代码**:后端代码通过 volume 挂载,改代码只需重启容器,无需重建镜像
3. **前端构建产物挂载**:前端 `dist/` 通过 volume 挂载,更新只需上传新构建产物
4. **数据库迁移**:将本地有数据的 `test_platform.db`(241 个 UI 用例)迁移到服务器新目录
---
## 二、需求内容
### 2.1 功能需求
#### 2.1.1 独立目录结构
```
/opt/plat-auto-test/ ← 独立部署目录(无 git,与另一服务完全隔离)
├── deploy/ ← 部署配置文件(Dockerfile、Compose、Nginx)
│ ├── docker-compose.yml
│ ├── Dockerfile.backend
│ ├── Dockerfile.frontend
│ └── nginx/default.conf
├── backend/ ← 后端源码(volume 挂载到容器)
│ ├── app/
│ ├── scripts/
│ └── requirements.txt
├── frontend/
│ └── dist/ ← 前端构建产物(volume 挂载到容器)
└── data/ ← 数据持久化
├── test_platform.db ← 有数据的数据库(241个UI用例)
├── screenshots/
└── reports/
```
#### 2.1.2 Volume 挂载方案
| 容器 | 镜像内容 | Volume 挂载 | 更新方式 |
|------|---------|-------------|---------|
| 后端 | Python 3.10 + Playwright + pip 依赖 | `backend/``/app/` | 上传代码 → `docker compose restart backend` |
| 前端 | nginx:alpine | `frontend/dist/``/usr/share/nginx/html` | 本地构建 → 上传 dist/ → `docker compose restart frontend` |
#### 2.1.3 更新流程对比
| 场景 | 当前方式(COPY 进镜像) | 优化后(Volume 挂载) |
|------|----------------------|---------------------|
| 改后端代码 | 上传代码 → 重建镜像(3-5min) → 重启 | 上传代码 → 重启容器(5s) |
| 改前端代码 | 本地构建 → 上传 → 重建镜像(3-5min) → 重启 | 本地构建 → 上传 dist/ → 重启容器(5s) |
| 更新数据库 | 上传 .db 文件 → 重启容器 | 上传 .db 文件 → 重启容器(不变) |
| 改配置(nginx/yml) | 上传 → 重建镜像 → 重启 | 上传 → 重启容器 |
### 2.2 非功能需求
#### 2.2.1 性能要求
- 后端容器重启时间 < 10 秒
- 前端容器重启时间 < 5 秒
- 首次部署总时间(含构建)< 15 分钟
#### 2.2.2 安全要求
- 独立目录不与另一服务共享
- 数据库文件权限设为 644(容器可读写)
- 避免将整个 backend 目录挂载到容器中的敏感路径
---
## 三、方案设计
### 3.1 后端 Dockerfile 改造
**改造前**:代码 COPY 进镜像,镜像体积大,代码更新需重建
```dockerfile
COPY backend/ .
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8001"]
```
**改造后**:镜像只装依赖,代码从 volume 挂载
```dockerfile
# 只复制 requirements.txt 并安装依赖
COPY backend/requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# 安装 Playwright Chromium
RUN playwright install chromium
# 不复制代码 —— 启动时从 volume 挂载
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8001"]
```
### 3.2 前端 Dockerfile 改造
**改造前**:镜像内包含构建产物,更新需重建
```dockerfile
FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
COPY deploy/nginx/default.conf /etc/nginx/conf.d/default.conf
```
**改造后**:镜像只含 nginx 配置,构建产物从 volume 挂载
```dockerfile
FROM nginx:alpine
# 只复制 nginx 配置(不变的部分)
COPY deploy/nginx/default.conf /etc/nginx/conf.d/default.conf
# 不复制 dist/ —— 启动时从 volume 挂载
```
### 3.3 docker-compose.yml 改造
**改造前**
```yaml
services:
backend:
volumes:
- ../data:/app/data # 只挂载数据库
frontend:
# 无 volume 挂载
```
**改造后**
```yaml
services:
backend:
volumes:
- /opt/plat-auto-test/data:/app/data
- /opt/plat-auto-test/backend:/app # 新增:挂载后端代码
frontend:
volumes:
- /opt/plat-auto-test/frontend/dist:/usr/share/nginx/html # 新增:挂载前端构建产物
```
---
## 四、验收标准
### 4.1 功能验收
| 验收项 | 验收标准 |
|--------|---------|
| 独立目录部署 | 服务在 `/opt/plat-auto-test/` 下正常运行 |
| 后端 volume 挂载 | 修改后端代码后重启容器,新代码生效 |
| 前端 volume 挂载 | 上传新构建产物后重启容器,新前端生效 |
| 数据库迁移 | 访问平台可看到 241 个 UI 用例 |
| 已有服务不受影响 | 8088 端口服务继续正常运行 |
### 4.2 性能验收
| 验收项 | 验收标准 |
|--------|---------|
| 后端重启时间 | 从执行命令到服务可用 < 10 秒 |
| 后端健康检查 | `curl http://localhost:8001/health` 返回 200 |
| 前端可访问 | `curl http://localhost/` 返回 200 |
---
## 五、风险评估
| 风险 | 概率 | 影响 | 缓解措施 |
|------|------|------|---------|
| 后端代码路径不一致 | 中 | 高 | 确保容器内路径 `/app` 与挂载路径匹配 |
| Python 依赖未安装 | 低 | 高 | 首次构建时确保 requirements.txt 安装完整 |
| 前端构建产物不完整 | 低 | 中 | 本地 `npm run build` 成功后上传 |
| 数据库文件权限问题 | 中 | 中 | 容器内 uid 1000 需有读写权限 |
| 旧容器未停止导致端口冲突 | 低 | 中 | 先停旧容器再启动新容器 |
---
## 六、附录
### 6.1 相关文档
| 文档 | 说明 |
|------|------|
| `Docs/部署方案/Linux服务器部署方案.md` | 原始部署方案 |
| `Docs/部署方案/Linux容器化部署_执行计划.md` | 原始部署执行计划 |
| `deploy/docker-compose.yml` | 主编排文件 |
| `deploy/Dockerfile.backend` | 后端 Dockerfile |
| `deploy/Dockerfile.frontend` | 前端 Dockerfile |
| `deploy/nginx/default.conf` | Nginx 配置 |
| `HANDOFF_UI自动化.md` | 项目交接文档 |
### 6.2 服务器信息
| 项目 | 值 |
|------|-----|
| 服务器 | 192.168.5.60 |
| 用户 | ubains |
| 操作系统 | Ubuntu 26.04 LTS |
| 已有服务 | `/opt/troubleshoot/` → 端口 8088 |
| 新部署目录 | `/opt/plat-auto-test/` |
| 新服务端口 | 80(前端)、8001(后端) |
\ No newline at end of file
此差异已折叠。
此差异已折叠。
......@@ -1240,7 +1240,6 @@
"resolved": "https://mirrors.cloud.tencent.com/npm/@types/lodash-es/-/lodash-es-4.17.12.tgz",
"integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"@types/lodash": "*"
}
......@@ -2007,15 +2006,13 @@
"version": "4.18.1",
"resolved": "https://mirrors.cloud.tencent.com/npm/lodash/-/lodash-4.18.1.tgz",
"integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==",
"license": "MIT",
"peer": true
"license": "MIT"
},
"node_modules/lodash-es": {
"version": "4.18.1",
"resolved": "https://mirrors.cloud.tencent.com/npm/lodash-es/-/lodash-es-4.18.1.tgz",
"integrity": "sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==",
"license": "MIT",
"peer": true
"license": "MIT"
},
"node_modules/lodash-unified": {
"version": "1.0.3",
......@@ -2287,7 +2284,6 @@
"integrity": "sha512-OL3GoQyoUdDt843DpVmDO6y2k1sc5IhUDSpu8XucEI+35neq5QivZ1iuegnpraEVTJXlQGK1gl27zKcTLEPbQw==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"chokidar": "^5.0.0",
"immutable": "^5.1.5",
......@@ -2338,7 +2334,6 @@
"integrity": "sha512-SNiDnXyHSrxVcIOtVbULzcTmniUiwcV7Nwdyj1twVubeTmbjoa8p69KKDpfkdoOavuM4/GRm1+ykI8qqnavHoA==",
"dev": true,
"license": "BSD-2-Clause",
"peer": true,
"dependencies": {
"@jridgewell/source-map": "^0.3.3",
"acorn": "^8.15.0",
......@@ -2363,7 +2358,6 @@
"resolved": "https://mirrors.cloud.tencent.com/npm/typescript/-/typescript-5.9.3.tgz",
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"devOptional": true,
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
......@@ -2377,7 +2371,6 @@
"resolved": "https://mirrors.cloud.tencent.com/npm/vite/-/vite-5.4.21.tgz",
"integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==",
"dev": true,
"peer": true,
"dependencies": {
"esbuild": "^0.21.3",
"postcss": "^8.4.43",
......@@ -2443,7 +2436,6 @@
"version": "3.5.39",
"resolved": "https://mirrors.cloud.tencent.com/npm/vue/-/vue-3.5.39.tgz",
"integrity": "sha512-xmZCYabFGcirU8r0fTuvl/LICc1OU620rnqepaJDL/a141ZigkG7AyaxQLdqJ02ZRYzWe6YPaDHeQx7MfknQfA==",
"peer": true,
"dependencies": {
"@vue/compiler-dom": "3.5.39",
"@vue/compiler-sfc": "3.5.39",
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论