跳转到内容

项目构建、部署与 Docker 安全执行

项目构建、部署与 Docker 安全执行

学习目标

  • 理解 ChatDev 的依赖管理(uv + pyproject.toml)与构建流程
  • 掌握 Docker 部署配置与安全执行机制
  • 了解 Makefile 目标与开发工作流
  • 理解热重载的安全设计(白名单 + 黑名单)

项目实践

依赖管理

ChatDev 使用 uv 作为 Python 包管理器,pyproject.toml 定义项目配置:

[project]
name = "DevAll"
version = "0.1.0"
requires-python = ">=3.12,<3.13"
dependencies = [
"pyyaml",
"openai",
"tenacity",
"mcp",
"fastmcp",
"faiss-cpu",
"fastapi==0.124.0",
"uvicorn",
"watchfiles",
"websockets",
"wsproto",
"pydantic==2.12.5",
"google-genai>=1.52.0",
"mem0ai>=1.0.9",
# ... 更多依赖
]
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.uv]
package = false # 不打包为发行版

关键设计决策

  • requires-python = ">=3.12,<3.13":锁定 Python 3.12,避免版本兼容性风险
  • package = false:不打包为可安装库,仅作为应用运行
  • fastapi==0.124.0:版本锁定,避免 API 破坏性变更

Makefile 目标

dev: # 同时启动前后端(开发模式)
sync: # 将 yaml_instance/ 同步到数据库
validate-yamls: # 校验所有 YAML 工作流文件
help: # 显示可用命令列表

make dev 的实现:

dev:
# 后端:uv run python server_main.py --port 8000 --reload
# 前端:cd frontend && VITE_API_BASE_URL=http://localhost:8000 npm run dev

Docker 部署

Dockerfile

FROM python:3.12-slim
# 安装系统依赖
RUN apt-get update && apt-get install -y nodejs npm
# 安装 Python 依赖
COPY requirements.txt .
RUN pip install -r requirements.txt
# 复制项目文件
COPY . /app
WORKDIR /app
# 安装前端依赖
RUN cd frontend && npm install
# 暴露端口
EXPOSE 8000 5173
# 启动命令
CMD ["python", "server_main.py", "--port", "8000"]

compose.yml

services:
chatdev:
build: .
ports:
- "8000:8000"
- "5173:5173"
env_file:
- .env.docker
volumes:
- ./WareHouse:/app/WareHouse # 持久化输出目录

热重载安全设计

ChatDev 的 --reload 机制经过两层防护:

第一层:白名单(监听目录限制)

RELOAD_SOURCE_DIRS = [
"check", "entity", "functions", "mcp_example",
"runtime", "schema_registry", "server",
"tools", "utils", "workflow",
]

仅当这些目录中的文件变化时触发重载。Agent 生成的文件(在 WareHouse/ 中)不触发。

第二层:黑名单(排除目录)

_RELOAD_EXCLUDE_DIRS = ("WareHouse", "logs", "data", "temp", "node_modules")
_RELOAD_EXCLUDE_MAX_DEPTH = 10
RELOAD_EXCLUDES = [
f"{d}{'/*' * (depth + 1)}"
for d in _RELOAD_EXCLUDE_DIRS
for depth in range(_RELOAD_EXCLUDE_MAX_DEPTH)
]
# 产出: WareHouse/*, WareHouse/*/*, ..., 10 层深度

为什么需要两层防护?

  • 白名单确保只监听源码
  • 黑名单作为第二道防线,即使文件在白名单外但被意外匹配也不会触发

watchfiles 依赖

if args.reload and not _watchfiles_available():
logger.warning(
"--reload is active but 'watchfiles' is not installed; uvicorn will "
"fall back to StatReload, which ignores --reload-exclude patterns."
)
  • watchfiles 已安装:支持排除模式(黑名单生效)
  • watchfiles 未安装:降级为 StatReload(忽略黑名单,仅靠白名单防护)

输出目录管理

WareHouse/ # Agent 执行结果输出
logs/ # 日志文件
data/ # 数据库文件(如 SQLite)
temp/ # 临时文件(自动清理)

这些目录通过 .gitignore 排除,不纳入版本控制。

问题与规避

问题表现规避策略
Python 版本不兼容<3.13 限制无法在 3.13 上运行使用 uv 管理 Python 版本
Docker 构建慢apt-get 和 pip install 耗时长使用多阶段构建 + 缓存层
热重载误触发即使有白名单仍被触发确保 watchfiles 已安装
WareHouse 目录挂载Docker 中目录不存在使用 volumes 自动创建
端口冲突8000 已被占用--port 参数指定其他端口

设计取舍

uv vs pip + requirements.txt

维度uvpip
安装速度极快(Rust 实现)
锁文件uv.lock(确定性)requirements.txt(需 freeze)
Python 管理内置需 pyenv 等
ChatDev 的选择✅ 使用❌ 仅保留 requirements.txt 兼容

ChatDev 保留 requirements.txt 是为了 Docker 兼容(pip 是 Dockerfile 中的默认安装方式)。

Docker vs 本地开发

维度Docker本地开发
环境一致性高(隔离)低(依赖本地环境)
启动速度慢(需构建镜像)
调试困难(需 attach)容易
ChatDev 的选择部署用开发用

参考来源