前言
在本地用 LangGraph 开发完一个 Agent 项目,准备部署到服务器上。结果一上服务器就傻眼了:系统自带 Python 2.7 ,而 langgraph-cli 要求 Python 3.10+,uv 更是想都别想。服务器上既装不了 uv,也装不了 langgraph-cli,langgraph build 这条路直接堵死。
但需求摆在那里:代码必须上服务器,必须用 Docker 跑起来。最后摸索出一条路:在本地用 langgraph dockerfile 生成 Dockerfile,把生成物连同代码一起传到服务器,服务器上只用原生的 docker build 构建。服务器上完全不需要 Python 3,也不需要任何 LangGraph CLI。
这篇博客记录一下完整的踩坑过程和最终方案,如果你也卡在"本地能跑、服务器 Python 太老"的困境里,应该能省你几个小时。
一、为什么不能用 langgraph build?
langgraph build 本质上是一个封装好的便捷命令,它内部会做几件事:拉取基础镜像、生成 Dockerfile、执行 docker build。问题在于,这个命令必须在装有 langgraph-cli 的环境里运行 ,而 CLI 本身依赖现代 Python 版本。
服务器 Python 2.7 意味着:
pip install langgraph-cli直接报语法错误或版本不兼容uv根本不支持 Python 2.7,无法安装- 即使手动把 CLI 的包拷过去,依赖树也跑不起来
所以核心思路变成:在本地完成 Dockerfile 的生成,服务器只负责执行 docker build 。docker build 本身不关心宿主机 Python 版本,它只读取 Dockerfile 和上下文文件。
二、本地生成 Dockerfile 的关键命令
LangGraph CLI 其实提供了一个专门用于生成 Dockerfile 的子命令,不需要触发构建:
bash
csharp
langgraph dockerfile ./Dockerfile --add-docker-compose
这个命令会基于项目根目录的 langgraph.json,分析依赖、图入口、环境变量等配置,生成一个可以直接用于 docker build 的 Dockerfile。加上 --add-docker-compose 还会同时生成 docker-compose.yml、.env 和 .dockerignore,省去手写的麻烦。
这里踩了第一个坑 :我一开始只生成了 Dockerfile,没加 --add-docker-compose,结果服务器上还得自己补 compose 文件,反而多花了时间。建议直接加这个 flag,一步到位。
生成后的文件结构大概是这样:
text
bash
项目根目录/
├── Dockerfile
├── docker-compose.yml
├── .env
├── .dockerignore
├── langgraph.json
├── requirements.txt (或 pyproject.toml)
└── 你的代码...
第二个坑 :langgraph dockerfile 生成的内容是快照式 的。如果你之后改了 langgraph.json(比如新增了依赖、改了图入口路径),必须重新运行生成命令 ,否则 Dockerfile 里的配置和你实际代码不匹配,构建出来的镜像会报错。我一开始改完 langgraph.json 直接传服务器构建,跑起来提示找不到图,排查了半天才发现 Dockerfile 还是旧的。
三、把生成物传到服务器
这一步没什么技术含量,但有两个细节值得注意:
第一,.dockerignore 要检查。 langgraph dockerfile --add-docker-compose 生成的 .dockerignore 通常会包含 __pycache__、.venv、.env 等。如果你的 .env 被 ignore 了,但 docker-compose.yml 又引用了它,服务器上启动时会报环境变量缺失。要么确保 .env 在传输时带上,要么在 compose 文件里用 environment 直接写死(不推荐,但应急可以)。
第二,依赖文件要一起传。 Dockerfile 里通常会有 COPY requirements.txt 或 COPY pyproject.toml 之类的指令。如果你只传了 Dockerfile 和代码,漏了依赖声明文件,docker build 会在 COPY 那一步直接失败。建议用 rsync 或者打包上传,确保项目根目录下所有 Dockerfile 引用到的文件都在。
四、服务器上直接 docker build
服务器上不需要 langgraph,不需要 uv,只需要 Docker。
bash
perl
docker build -t my-langgraph-app:v1 .
第三个坑 :基础镜像的拉取。langgraph dockerfile 生成的 Dockerfile 第一行通常是类似 FROM langchain/langgraph-api:0.2.x 的指令。服务器如果无法直接访问 Docker Hub,docker build 会卡在拉取基础镜像那一步。我遇到的报错是 failed to resolve source metadata,后来在服务器上配置了国内镜像加速器才解决。如果你用的是公司内网,可能需要提前把基础镜像 docker pull 下来再 docker tag 成 Dockerfile 里写的名字。
构建成功后,用 docker images 能看到镜像。启动方式取决于你生成的 docker-compose.yml:
bash
docker compose up -d
或者直接用 docker run,端口和挂载按需调整。LangGraph API Server 默认监听 8123 端口,健康检查端点是 /ok。
五、验证与收尾
服务起来之后,先确认健康检查通过:
bash
arduino
curl http://127.0.0.1:8123/ok
如果返回正常,再用前端或 curl 调一次真实的对话接口。第四个坑:LangGraph 的流式输出在 Nginx 反代下容易被缓冲,导致前端看起来"卡住"或者一次性弹出所有内容。如果前面有 Nginx,记得在 location 里加:
nginx
ini
proxy_buffering off;
proxy_set_header X-Accel-Buffering no;
六、总结一下踩坑清单
| 坑 | 表现 | 解法 |
|---|---|---|
| 只生成 Dockerfile 没生成 compose | 服务器上手动补文件 | langgraph dockerfile ./Dockerfile --add-docker-compose |
| 改配置后没重新生成 | 构建出的镜像图入口找不到 | 每次改 langgraph.json 后重新跑生成命令 |
.dockerignore 排除了 .env |
启动时报环境变量缺失 | 检查 ignore 文件,或手动补 .env |
| 基础镜像拉取失败 | docker build 卡住或报错 |
配置镜像加速器,或提前 docker pull + docker tag |
| Nginx 缓冲流式输出 | 前端对话一次性弹出 | proxy_buffering off |
核心结论就一句话:langgraph dockerfile 是独立于 langgraph build 的纯生成命令,它只需要本地有 CLI,生成后的产物在服务器上用原生 Docker 就能消费。 服务器 Python 版本再老,只要 Docker 能跑,这条路就走得通。
如果你也在类似的老旧服务器环境里折腾 LangGraph 部署,希望这篇能帮你少走几个弯路。