# 容器化部署优化：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（后端） |