系列05-FastAPI 测试平台 Docker 部署踩坑记录(OpenCloudOS / 腾讯云)
用 Docker Compose 在 Linux 上一键拉起测试平台(MySQL + Redis + RabbitMQ + MinIO + FastAPI + Nginx),听起来很美好。
我在 腾讯云 CVM + OpenCloudOS 9 上部署 BrickCore (FastAPI + Vue3 开源测试平台)时,踩过不少坑------不少文档不会写的那种。本文按 现象 → 原因 → 处理 整理,方便你搜「docker 部署踩坑」「OpenCloudOS nodejs」时能直接对照。
本文是 排错向 ,不是从零教程;完整逐步部署见 Gitee 仓库
docs-site/guide/docker-deploy.md。
一、先看清要拉起什么
根目录 docker-compose.yml 一次启动:
| 容器/服务 | 作用 |
|---|---|
| MySQL | 业务数据、执行记录 |
| Redis | 缓存、实时日志 |
| RabbitMQ | UI/性能任务队列(Runner 消费) |
| MinIO | UI 截图、视频、附件 |
| backend | FastAPI 应用 |
| nginx | 前端静态资源 + API 反代 |
访问路径:浏览器 → 80 端口 → Nginx → 前端 / API。
1.1 源码视角:环境变量从 compose 到 Backend
很多「部署成功但功能异常」来自 compose 注入值 与 Python 读取逻辑 不一致。对照下面两处最快定位:
compose 侧 (docker-compose.yml 的 backend 服务):
yaml
environment:
MINIO_PUBLIC_ENDPOINT: ${MINIO_PUBLIC_ENDPOINT:-localhost:9200}
RUNNER_MIDDLEWARE_ISOLATION: "1"
DATABASE_USER: admin
Backend 侧 (backend/app/core/minio_client.py):
python
self.endpoint = os.getenv('MINIO_ENDPOINT', 'localhost:9200')
self.public_endpoint = os.getenv('MINIO_PUBLIC_ENDPOINT', self.endpoint)
# 预签名 URL 用 public_endpoint --- 浏览器/Runner 必须能访问
return f"{protocol}://{self.public_endpoint}/{target_bucket}/{decoded}"
若 .env 或 compose 里仍是 localhost:9200,UI 报告截图 URL 会指向测开本机,线上必裂图。改公网 IP 后需 docker compose up -d --force-recreate backend 让进程重读环境变量。
Runner 连 MQ/Redis 的公网 host 也常从 MINIO_PUBLIC_ENDPOINT 推导(backend/app/core/config.py 的 RUNNER_MIDDLEWARE_ISOLATION=1 分支)------这就是为什么安全组不能只开 80,还要开 25672 / 26379 / 9200(见后文坑 5)。
二、坑 1:同时跑了 docker-services.yml,MySQL 端口冲突
现象
text
Error: bind: address already in use
或 mysql 容器反复 Restarting
原因
仓库里可能有 docker-services.yml (仅中间件,给本机开发用)。若在同一台服务器 上先跑了它,再跑全栈 docker-compose.yml,会 起两套 MySQL/Redis,端口打架。
处理
bash
# 生产/演示机:只用全栈
docker compose down
docker compose up -d --build
# 切勿在同一机器再执行
# docker compose -f docker-services.yml up -d
记住 :云服务器上 只保留一套 compose 全栈。
三、坑 2:OpenCloudOS 安装 Node.js 装错源
现象
bash
dnf module install nodejs
# 或 curl -fsSL https://rpm.nodesource.com/setup_20.x | bash -
报 RPM 识别错误、依赖冲突,或装出来的 node -v 过低,npm run build 失败。
原因
OpenCloudOS 9 没有 好用的 dnf module nodejs;NodeSource 一键脚本在该系统上常不兼容。
处理(推荐)
bash
sudo dnf makecache
sudo dnf install -y git epol-release
sudo dnf makecache
sudo dnf install -y nodejs npm
node -v # 期望 v18+
npm -v
仍不够时,用 NVM 装 Node 20:
bash
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
source ~/.bashrc
nvm install 20
node -v
前端必须先 build 成功 ,再 docker compose up,否则 Nginx 里可能是空目录或旧包。
bash
cd BrickCore/frontend && npm install && npm run build && cd ..
四、坑 3:安全组只开了 80,Runner / 截图全失败
现象
- 平台能登录,但 UI 自动化任务一直排队
- Runner 显示离线或上线后收不到任务
- UI 报告没有截图,MinIO 上传报错
原因
| 端口 | 用途 | 谁要连 |
|---|---|---|
| 80 | Web 页面 | 浏览器(必开) |
| 25672 | RabbitMQ | Runner 机器 |
| 26379 | Redis | Runner 机器 |
| 9200 | MinIO | Runner 机器 |
只开 80,平台 Web 正常,但 执行器与存储 连不上。
处理
腾讯云 安全组 → 入站规则:
- TCP 80 :
0.0.0.0/0或办公网(Web 必开) - TCP 25672 / 26379 / 9200 :仅放行 Runner 所在机器的公网 IP,不要对全网开放
本机测试 Runner 时,Runner 机器也要能访问上述端口。
五、坑 4:MINIO_PUBLIC_ENDPOINT 未改,截图 URL 错误
现象
UI 用例跑完,报告里截图裂图;浏览器 Network 里 MinIO 地址是 localhost:9200 或内网 IP。
原因
docker-compose.yml 里 MinIO 对外访问地址默认可能是容器内网配置,Runner 上传成功后,前端拼的截图 URL 仍指向错误 host。
处理
部署前改环境变量(示例):
yaml
# docker-compose.yml 或 .env
MINIO_PUBLIC_ENDPOINT: <你的公网IP>:9200
改完后:
bash
docker compose up -d --force-recreate
六、坑 5:没 build 前端就 compose,页面空白或 404
现象
docker compose up 成功,打开 IP 白屏、静态资源 404。
原因
Nginx 挂载的是 frontend/dist,未执行 npm run build 时目录为空或不存在。
处理
bash
git clone https://gitee.com/BanZhuanKeOrz/BrickCore.git
cd BrickCore
cd frontend && npm install && npm run build && cd ..
docker compose up -d --build
七、坑 6:数据库初始化字符集不对
现象
导入 database.sql 后中文乱码;或登录报错表不存在。
原因
- 未导入
database.sql - mysql 客户端未指定 utf8mb4
处理
等 backend 日志出现「启动后端服务」后:
bash
docker exec -i fastapi_mysql mysql \
--default-character-set=utf8mb4 \
-uadmin -pBrickCore123456 fastapi < database.sql
默认账号:admin / BrickCore123456(部署后务必修改)。
八、坑 7:内存不足,build 或 MySQL OOM
现象
docker compose build 中途 killed;MySQL 容器 Exit 137。
原因
2GB 机器跑全栈 + frontend build 偏紧;OpenCloudOS 上 swap 未开。
处理
| 建议 | 说明 |
|---|---|
| 规格 ≥ 4GB | 首次 build 较稳 |
| 开 swap | 临时缓解 OOM |
| 分开 build | 在本地 build 好 frontend 再 scp dist(备选) |
九、坑 8:Docker Hub 拉镜像极慢或超
现象
docker compose pull / build 卡在 Downloading 或 context deadline exceeded。
处理
配置 Docker 镜像加速 (腾讯云、阿里云等提供加速器地址),编辑 /etc/docker/daemon.json 后 systemctl restart docker。
Gitee clone 慢时,可先在本地打包上传,与 Docker 无关但常一起遇到。
十、推荐部署顺序(精简速查)
按顺序做,可避开大部分坑:
bash
# 1. 安全组:80 + Runner 所需端口
# 2. 安装 git、nodejs(epol-release,勿用 NodeSource 脚本)
git clone https://gitee.com/BanZhuanKeOrz/BrickCore.git
cd BrickCore
# 3. 构建前端
cd frontend && npm install && npm run build && cd ..
# 4. 改 MINIO_PUBLIC_ENDPOINT 为公网 IP:9200
# 5. 只跑全栈 compose
docker compose up -d --build
docker compose logs -f backend # 等到启动成功
# 6. 导入数据库
docker exec -i fastapi_mysql mysql --default-character-set=utf8mb4 \
-uadmin -pBrickCore123456 fastapi < database.sql
浏览器访问:http://<公网IP>/,登录 admin / BrickCore123456。
十一、常见问题速查表
| 现象 | 优先检查 |
|---|---|
| 端口冲突 | 是否误跑 docker-services.yml |
| npm run build 失败 | Node 版本、epol-release、NVM |
| 页面空白 | frontend/dist 是否 build |
| UI 任务不跑 | 25672 安全组、Runner 是否上线 |
| 无截图 | 9200 安全组、MINIO_PUBLIC_ENDPOINT |
| 中文乱码 | database.sql 导入加 utf8mb4 |
| 容器反复重启 | 内存、docker logs 具体服务 |
十二、小结
- 云服务器 只用
docker-compose.yml全栈,别混docker-services.yml。 - OpenCloudOS 装 Node:epol + dnf,慎用 NodeSource 脚本。
- 安全组 80 不够,Runner 还需 25672/26379/9200。
- MinIO 公网地址必须改,否则 UI 截图不可用。
- 先 npm run build 再 compose;数据库用 utf8mb4 导入。
附录 A:关键配置在源码里的位置
踩坑往往出在 compose 环境变量 与 Backend 读取逻辑 不一致,对照源码更快定位。
A.1 MINIO_PUBLIC_ENDPOINT 如何影响 Runner
python
# backend/app/core/minio_client.py(概念)
self.public_endpoint = os.getenv('MINIO_PUBLIC_ENDPOINT', self.endpoint)
docker-compose.yml 里若仍是 localhost:9200,预签名 URL 会带内网地址,浏览器/Runner 上传后报告裂图。改公网 IP 后需 docker compose up -d --force-recreate backend。
A.2 Runner 中间件公网地址推导
python
# backend/app/core/config.py
# RUNNER_MIDDLEWARE_ISOLATION=1 时,connect 下发给客户端的 MQ/Redis host
# 常由 MINIO_PUBLIC_ENDPOINT 的 host 部分推导公网 IP
public_host = _host_from_endpoint(os.getenv("MINIO_PUBLIC_ENDPOINT", ""))
因此系列里「只开 80」不够:25672/26379/9200 是给 Runner 进程 连 MQ/Redis/MinIO,不是给访客浏览器。
A.3 演示机 .env 与 compose 变量注入
CE 演示 compose 使用 ${MYSQL_PASSWORD}、${MINIO_ACCESS_KEY} 等从 仓库根 .env 读取(该文件 gitignore)。backend 容器内 DATABASE_USER 可能是 admin 而非 fastapi------若用错账号,Runner legacy 直连会认证失败。
A.4 restart.sh 与分支
bash
# restart.sh --- 自动检测 origin/master 或 origin/main
git fetch origin "$GIT_BRANCH"
git reset --hard "origin/$GIT_BRANCH"
演示机 Gitee 默认分支是 master ;若脚本写死 main 会 pull 失败(已在 restart.sh 做自动检测)。
A.5 读代码排错顺序
| 现象 | 优先看 |
|---|---|
| 截图 URL 错 | minio_client.py、docker-compose.yml MINIO_PUBLIC |
| Runner 连不上 MQ | compose 端口映射、runner_connect.py 下发 host |
| 前端白屏 | nginx-docker.conf 是否挂载 frontend/dist |
| 迁移失败 | backend 启动日志 aerich upgrade |
关于 BrickCore
以上踩坑来自部署开源项目 BrickCore 的真实过程,供同类 FastAPI + Vue3 测试平台参考:
| 项 | 链接 |
|---|---|
| 源码 | https://gitee.com/BanZhuanKeOrz/BrickCore |
| 完整部署文档 | https://gitee.com/BanZhuanKeOrz/BrickCore/blob/main/docs-site/guide/docker-deploy.md |
| 在线体验 | http://43.142.83.156/ |
支持与交流
- 觉得有用欢迎 Star ⭐
- 部署问题:Gitee Issues 或评论区留言(可贴
docker compose logs片段)