12 KiB
DeerFlow 后端 Linux Docker 部署指南
本文档说明如何在 Linux + Docker 环境下一键部署 DeerFlow 后端(Gateway API,默认端口 8001)。
部署目录:offline-backend-20260512/
1. 架构概览
┌─────────────────────────────────────────────────────┐
│ Linux 宿主机 │
│ ┌───────────────────────────────────────────────┐ │
│ │ Docker 容器: deerflow-backend │ │
│ │ ┌─────────────────────────────────────────┐ │ │
│ │ │ Gateway API (uvicorn, port 8001) │ │ │
│ │ │ + LangGraph Agent Runtime │ │ │
│ │ └─────────────────────────────────────────┘ │ │
│ │ 挂载卷: │ │
│ │ config.yaml / .env │ │
│ │ backend/ 源码(可热更新 Python 代码) │ │
│ │ data/ → .deer-flow 持久化数据 │ │
│ └───────────────────────────────────────────────┘ │
│ │ 8001 │
│ ▼ │
│ 前端 / Nginx / 其他服务 │
└─────────────────────────────────────────────────────┘
持久化数据(挂载到 data/):
| 路径 | 说明 |
|---|---|
data/data/deerflow.db 或 checkpoints.db |
LangGraph checkpoint(SQLite) |
data/data/ |
业务 SQLite 文件(未切 MySQL 时) |
data/python-vendor/ |
离线安装的 Python 包(asyncmy、croniter 等) |
data/users/ |
用户线程、上传、记忆等 |
data/archives/ |
会话归档 |
2. 服务器要求
| 项目 | 最低要求 |
|---|---|
| 操作系统 | Linux x86_64(CentOS 7+、Ubuntu 20.04+、Debian 11+ 等) |
| Docker | 20.10+ |
| Docker Compose | V2(docker compose 命令可用) |
| 内存 | 建议 4 GB+ |
| 磁盘 | 建议 20 GB+(含镜像、数据、日志) |
| 网络 | 能访问 LLM API;内网部署可配置 Python 私服 |
2.1 安装 Docker(如未安装)
Ubuntu / Debian:
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker "$USER"
newgrp docker
验证:
docker --version
docker compose version
3. 部署包准备
将以下内容上传到服务器(例如 /opt/deerflow/offline-backend-20260512):
offline-backend-20260512/
├── deploy.sh # 一键部署脚本(主入口)
├── start_backend.sh # 启动(deploy.sh 的别名)
├── stop_backend.sh # 停止
├── docker-compose.yaml
├── .env.example
├── config.yaml # 应用配置
├── skill_evolution.json
├── backend/ # 后端源码 + Dockerfile + wheelhouse
│ ├── Dockerfile
│ ├── wheelhouse/ # 离线 Python 包
│ └── ...
├── scripts/
│ └── container-entrypoint.sh
└── data/ # 首次部署后自动创建
4. 一键部署(推荐)
4.1 配置环境变量
cd /opt/deerflow/offline-backend-20260512
cp .env.example .env
vi .env
必须修改的项:
# 至少配置一个可用模型的 API Key
DEEPSEEK_API_KEY=sk-xxxxxxxx
# JWT 密钥,部署后不要随意更改
AUTH_JWT_SECRET=your-long-random-secret
# 前端实际访问地址(CORS)
GATEWAY_CORS_ORIGINS=http://192.168.1.100:5174,http://localhost:5174
使用 MySQL 时(config.yaml 中 database.backend: mysql):
# 不要用 127.0.0.1 指向宿主机 MySQL;密码特殊字符须 URL 编码
MYSQL_DATABASE_URL=mysql+asyncmy://user:pass@192.168.1.100:3306/deerflow?charset=utf8mb4
内网无法访问公网 PyPI 时:
UV_INDEX_URL=http://your-python-mirror/simple
PIP_INDEX_URL=http://your-python-mirror/simple
UV_TRUSTED_HOST=your-python-mirror
PIP_TRUSTED_HOST=your-python-mirror
4.2 检查 config.yaml
确认模型配置、沙箱模式、数据库配置正确。config.yaml 中与 $ 开头的值会从 .env 读取,例如 $MYSQL_DATABASE_URL。
4.3 执行一键部署
chmod +x deploy.sh start_backend.sh stop_backend.sh scripts/container-entrypoint.sh
bash deploy.sh
脚本会自动:
- 检查 Docker 环境
- 创建
data/目录和兼容符号链接 - 若无
.env则从.env.example复制 - 构建 Docker 镜像(或加载离线 tar)
- 启动容器并做健康检查
4.4 验证
curl http://127.0.0.1:8001/health
# 期望返回 JSON,HTTP 200
curl -s http://127.0.0.1:8001/openapi.json | head
浏览器访问 API 文档:http://<服务器IP>:8001/docs
5. 常用运维命令
| 操作 | 命令 |
|---|---|
| 一键部署/启动 | bash deploy.sh 或 bash start_backend.sh |
| 停止 | bash deploy.sh down 或 bash stop_backend.sh |
| 重启 | bash deploy.sh restart |
| 查看状态 | bash deploy.sh status |
| 查看日志 | bash deploy.sh logs |
| 仅构建镜像 | bash deploy.sh build |
| 健康检查 | bash deploy.sh health |
5.1 自定义端口
HOST_PORT=9001 bash deploy.sh up
5.2 离线镜像模式(内网/无法访问 docker.io 时必用)
典型失败日志:
failed to fetch anonymous token: Get "https://auth.docker.io/token...": i/o timeout
说明服务器访问不了 Docker Hub,不能在线 build,必须用离线 tar。
步骤 1:在有公网的机器上导出镜像
bash scripts/export-offline-image.sh
# 产出: deerflow-backend-offline-image-20260505.tar
步骤 2:上传到内网服务器部署目录
步骤 3:内网服务器加载并启动
DEPLOY_MODE=offline \
IMAGE_TAR=./deerflow-backend-offline-image-20260505.tar \
IMAGE_TAG=deerflow-backend-offline:20260505 \
bash deploy.sh up
若 tar 已在目录中,deploy.sh 会自动检测并切换为离线模式。
或分步:
bash deploy.sh load
IMAGE_TAG=deerflow-backend-offline:20260505 bash deploy.sh up
5.3 配置 Docker 镜像加速(可选,有内网镜像源时)
编辑 /etc/docker/daemon.json:
{
"registry-mirrors": [
"https://你的内网或国内镜像地址"
],
"dns": ["114.114.114.114", "223.5.5.5"]
}
sudo systemctl daemon-reload
sudo systemctl restart docker
bash deploy.sh build
6. 前端对接
前端需配置后端地址(Vite 环境变量示例):
VITE_BACKEND_BASE_URL=http://192.168.1.100:8001
VITE_LANGGRAPH_BASE_URL=http://192.168.1.100:8001/api
确保 .env 中 GATEWAY_CORS_ORIGINS 包含前端实际 Origin。
7. MySQL 切换(可选)
若初始使用 SQLite,后续可切换到 MySQL:
bash stop_backend.sh
MYSQL_DATABASE_URL='mysql+asyncmy://user:pass@192.168.1.100:3306/deerflow?charset=utf8mb4' \
bash switch_database_to_mysql.sh
bash start_backend.sh
详细说明见 MYSQL_SWITCH_RELEASE_NOTES_LINUX_DOCKER_ZH.md。
8. 代码热更新
当前部署方式将 backend/app、backend/packages 等目录挂载进容器,更新 Python 代码后重启即可生效,无需重新构建镜像:
# 上传新代码后
bash deploy.sh restart
若修改了 pyproject.toml / 依赖,需重新构建:
bash deploy.sh build
bash deploy.sh restart
9. 目录与卷说明
| 宿主机 | 容器内 | 说明 |
|---|---|---|
./config.yaml |
/app/config.yaml |
主配置(只读) |
./.env |
环境变量注入 | 密钥、CORS 等 |
./backend/app |
/app/backend/app |
应用层代码 |
./backend/packages |
/app/backend/packages |
harness 框架 |
./backend/skills |
/app/backend/skills |
Agent Skills |
./backend/wheelhouse |
/app/wheelhouse |
离线 wheel 包 |
./data |
/app/backend/.deer-flow |
全部运行时数据 |
10. 故障排查
10.0 Docker 未运行或无权限
报错示例:
[FAIL] Docker 未运行或无权限...
第一步:看具体原因
docker info
情况 A:permission denied(最常见)
说明当前用户不在 docker 组:
# 把当前用户加入 docker 组
sudo usermod -aG docker "$USER"
# 让组权限立即生效(或重新 SSH 登录)
newgrp docker
# 验证
docker info
docker ps
# 再部署
bash deploy.sh
若仍不行,确认 socket 权限:
ls -l /var/run/docker.sock
# 期望类似: srw-rw---- root docker ...
情况 B:Cannot connect to the Docker daemon
说明 Docker 服务没起来:
sudo systemctl status docker
sudo systemctl start docker
sudo systemctl enable docker
docker info
bash deploy.sh
情况 C:未安装 Docker
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker "$USER"
newgrp docker
bash deploy.sh
临时绕过(仅测试用,不推荐生产)
sudo bash deploy.sh
10.1 容器启动后立即退出
bash deploy.sh logs
常见原因:
.env中 API Key 或AUTH_JWT_SECRET未配置config.yaml语法错误- MySQL 连接失败(检查
MYSQL_DATABASE_URL是否用了容器可达的 IP) - 缺少
asyncmy(MySQL 模式):确认backend/wheelhouse中有对应 wheel,或配置 Python 私服
10.1.1 脚本报 $'\r': command not found 或 pipefail: invalid option
这是 Windows 换行符(CRLF) 导致的。在 Linux 上执行:
sed -i 's/\r$//' deploy.sh start_backend.sh stop_backend.sh scripts/container-entrypoint.sh switch_database_to_mysql.sh
chmod +x deploy.sh start_backend.sh stop_backend.sh scripts/container-entrypoint.sh
bash deploy.sh
或在 Windows 上传前,用 VS Code 右下角把文件编码改为 LF。
10.1.2 构建时报 .venv cannot be used because it is not a valid Python environment
原因:开发机(尤其 Windows)上的 backend/.venv 被打包进 Docker 构建上下文,Linux 容器内无法使用。
解决:仓库已添加 .dockerignore 排除 .venv。更新代码后重新构建:
bash deploy.sh build
# 或
bash deploy.sh up
若仍报错,手动删除后再构建:
rm -rf backend/.venv
bash deploy.sh build
10.2 健康检查失败
docker ps -a
docker logs deerflow-backend --tail 100
curl -v http://127.0.0.1:8001/health
确认端口未被占用:
ss -tlnp | grep 8001
10.3 前端报 CORS / Failed to fetch
检查 .env:
GATEWAY_CORS_ORIGINS=http://你的前端地址:端口
修改后重启:
bash deploy.sh restart
10.4 Docker 权限问题
sudo usermod -aG docker "$USER"
newgrp docker
10.5 沙箱需要 Docker-in-Docker
若 config.yaml 使用 AioSandboxProvider,容器需挂载宿主机 Docker socket(默认已挂载 /var/run/docker.sock)。确认:
ls -l /var/run/docker.sock
11. 生产环境建议
- 反向代理:前面加 Nginx,配置 HTTPS 和限流
- 防火墙:仅开放必要端口(如 443、8001 内网)
- 备份:定期备份
data/目录和config.yaml、.env - 日志:配置 Docker 日志轮转(
/etc/docker/daemon.json中log-opts) - 资源:根据并发调整
GATEWAY_WORKERS(.env,默认 2) - 文档:生产环境建议
GATEWAY_ENABLE_DOCS=false
12. 回滚
bash stop_backend.sh
# 恢复配置和数据备份
cp data/backups/xxx/config.yaml.bak config.yaml
cp data/backups/xxx/env.bak .env
cp -a data.bak data
bash start_backend.sh
13. 相关文档
- MYSQL_SWITCH_RELEASE_NOTES_LINUX_DOCKER_ZH.md — MySQL 切换
- backend/docs/BACKEND_RUN_STOP_ZH.md — 本地非 Docker 启停
- backend/docs/CONFIGURATION.md — 配置项详解