# CCDI Docker 部署设计

**日期**: 2026-03-13

**目标**: 将当前项目的前端、后端与 `lsfx mock server` 打包后上传到服务器 `116.62.17.81:9444` 的 `/volume1/webapp/ccdi`，并使用 Docker 统一部署运行。

## 背景与约束

- 前端对外端口固定为 `62319`
- 后端对外端口固定为 `62318`
- `lsfx mock server` 对外端口固定为 `62320`
- 后端运行时必须使用 Java 21
- 后端运行 profile 固定为 `local`
- 后端继续使用现有 [`application-local.yml`](/D:/ccdi/ccdi/ruoyi-admin/src/main/resources/application-local.yml) 中的 MySQL、Redis 与 `lsfx.api.base-url`
- `lsfx.api.base-url` 当前为 `http://localhost:8000`，希望不改动既有配置
- 服务端部署根目录固定为 `/volume1/webapp/ccdi`

## 方案选择

### 方案一：`mock server` 与后端共用网络命名空间

前端、后端、`mock server` 全部使用 Docker 部署，其中 `lsfx mock server` 通过 `network_mode: "service:backend"` 与后端共享网络命名空间。

优点：

- 不需要修改 `application-local.yml` 中的 `http://localhost:8000`
- 后端容器内访问 `localhost:8000` 时，实际就是同网络命名空间内的 `mock server`
- 对外暴露前端、后端和 `lsfx mock server` 端口，同时仍保持后端对 `localhost:8000` 的兼容访问

缺点：

- Compose 编排方式比普通三容器互联稍特殊

### 方案二：三服务独立组网

后端访问 `http://lsfx-mock-server:8000`。

优点：

- Compose 结构最常规

缺点：

- 需要修改现有 `local` 配置，不符合本次要求

### 方案三：本地构建镜像后上传镜像包

优点：

- 服务器上不需要源码级构建

缺点：

- 容易受到本地与服务器架构差异影响
- 镜像体积大，上传与迭代成本高

## 最终方案

采用方案一。

## 部署架构

### 前端

- 本地执行 `npm run build:prod`
- 使用 Nginx 容器托管 `ruoyi-ui/dist`
- Nginx 将 `/prod-api` 与 `/v3/api-docs` 反向代理到后端容器 `http://backend:8080`
- Docker 对外暴露 `62319`

### 后端

- 本地执行 `mvn clean package -DskipTests`
- 使用 Java 21 运行 `ruoyi-admin/target/ruoyi-admin.jar`
- 通过环境变量设置：
  - `SPRING_PROFILES_ACTIVE=local`
  - `RUOYI_PROFILE=/app/data/ruoyi`
- Docker 对外暴露 `62318`
- 同时额外映射 `62320 -> 8000`，让宿主机可直接访问共享网络命名空间中的 `lsfx mock server`

### LSFX Mock Server

- 将现有 FastAPI 实现整理为主仓库正式目录
- 使用 Python 3.11 容器运行
- 默认监听 `8000`
- 通过后端共享网络命名空间，对外暴露 `62320`
- 通过 `network_mode: "service:backend"` 让后端继续使用 `http://localhost:8000`

## 目录规划

服务器目录规划如下：

```text
/volume1/webapp/ccdi/
├── docker-compose.yml
├── .env
├── deploy/
│   ├── deploy.ps1
│   └── remote-deploy.py
├── docker/
│   ├── backend/Dockerfile
│   ├── frontend/Dockerfile
│   ├── frontend/nginx.conf
│   └── mock/Dockerfile
├── backend/
│   └── ruoyi-admin.jar
├── frontend/
│   └── dist/
├── lsfx-mock-server/
└── runtime/
    ├── ruoyi/
    └── logs/
```

## 关键配置设计

### `ruoyi.profile`

当前 [`application-local.yml`](/D:/ccdi/ccdi/ruoyi-admin/src/main/resources/application-local.yml) 未定义 `ruoyi.profile`。后端代码中的 [`RuoYiConfig.java`](/D:/ccdi/ccdi/ruoyi-common/src/main/java/com/ruoyi/common/config/RuoYiConfig.java) 依赖该值计算上传、导入与头像目录。

因此在 Docker 运行时通过环境变量补充：

```text
RUOYI_PROFILE=/app/data/ruoyi
```

并挂载到服务器目录，确保容器重启后数据保留。

### 反向代理

前端仍保持生产构建时的 `VUE_APP_BASE_API=/prod-api`，避免改动业务代码。Nginx 负责将：

- `/prod-api/` 转发到 `http://backend:8080/`
- `/v3/api-docs/` 转发到 `http://backend:8080/v3/api-docs/`

## 部署流程

1. 本地整理并提交部署文件
2. 本地打包前端与后端产物
3. 本地通过 SSH/SFTP 上传到服务器目标路径
4. 远端执行 `docker compose up -d --build`
5. 验证前端、后端、`mock server` 与代理链路

## 验证点

- `http://116.62.17.81:62319` 可打开前端
- `http://116.62.17.81:62318/swagger-ui/index.html` 可访问后端文档
- `http://116.62.17.81:62320/docs` 可访问 `lsfx mock server` 文档
- 前端登录与接口请求经 `/prod-api` 正常转发
- 后端容器可访问 `http://localhost:8000`
- `mock server` 健康检查正常

## 风险与处理

- 若服务器仅支持 `docker-compose`，部署脚本需兼容 `docker compose` 与 `docker-compose`
- 若服务器无法访问 `192.168.0.111` 上的 MySQL/Redis，则后端启动会失败；本次不改该配置
- 若服务器无 Docker 运行环境，需要先补齐 Docker 与 Compose 插件
