Windows 下 Docker 部署 RAGFlow 实录:从 502 到“真香”的 3 小时排雷
本以为
docker compose up -d一把梭,结果接连踩进镜像拉取超时、80 端口被锁、Nginx 疯狂 502 的连环坑。这篇文章把硬骨头一块块啃下来的全过程,以及最终那行RAGFlow server is ready after 390s背后的真实原因,都摊开来讲。
资源链接:https://download.csdn.net/download/u012551928/93315046
为什么要折腾 RAGFlow
团队需要一个开箱即用的 RAG 知识库系统,调研了一圈,RAGFlow 的文档预览、版面识别和可编排的 Agent 机制最贴合需求。官方推荐 Docker 部署,Windows 机器上一套 WSL2 + Docker Desktop 就能干,省去配 Linux 虚拟机的麻烦。
先说机器配置:Win11 专业版,16GB 内存,i7-10700,Docker Desktop 开了 WSL2 后端,分配了 8GB 内存和 4 核。官方建议 16GB 起步,内存不足的话后面 Elasticsearch 和 MySQL 会抢资源,容易 OOM。

第一步:拉代码,配环境
git clone https://github.com/infiniflow/ragflow.git
cd ragflow/docker
这里有个习惯:永远不要在 Windows 文件系统直接跑 Docker 挂载,性能差且权限容易乱。我把 repo 直接克隆到了 WSL 的 ~/workspace 下(\\wsl.localhost\Ubuntu\home\xxx\workspace),用 VSCode 的 Remote-WSL 打开,所有 docker 命令都在 WSL 里执行。
第二步:调整 vm.max_map_count(Elasticsearch 的硬要求)
ES 需要内存映射区域数量不低于 262144,否则启动就崩。Windows 下得进 Docker 的 Linux 内核改:
wsl -d docker-desktop
sysctl -w vm.max_map_count=262144
exit
这条命令每次重启电脑都会重置,我干脆写了个 .bat 开机自启,省得忘了。
第三步:起服务,第一次翻车(镜像拉取超时)
执行:
docker compose -f docker-compose.yml up -d
然后看到 valkey/valkey 这个镜像卡住,最后报:
net/http: timeout awaiting response headers
Docker 默认的 registry 在国内慢得像蜗牛。虽然我在 Docker Desktop 里配了 registry-mirrors 指向 docker.1ms.run,但这家源当天似乎挂了。
换源: 进 Settings → Docker Engine,把 registry-mirrors 改成:
https://docker.m.daocloud.io
https://docker.rainbond.cc
Apply & Restart。之后重新 docker compose up -d,镜像拉取速度瞬间到几十 MB/s。
第四步:80 端口被 Windows 锁死(Permission denied)
所有镜像拉完,容器纷纷启动,但 ragflow-cpu 报错退出:
listen tcp 0.0.0.0:80: bind: An attempt was made to access a socket in a way forbidden by its access permissions.
Windows 的 HTTP.sys 驱动经常霸占 80 端口(IIS、SQL Server Reporting Services 都可能)。关掉这些服务太麻烦,我选择改端口映射。
打开 docker/docker-compose.yml(实际上是 include.txt 引用的基础文件,但最终生效的是 .env 里的变量),发现 RAGFlow 用环境变量定义端口:
ports:
- ${SVR_WEB_HTTP_PORT}:8899
于是编辑同目录下的 .env 文件,加上:
SVR_WEB_HTTP_PORT=8899
这样宿主机走 8899,容器内依然走 8899(注意默认是 80:80,这里改成了 8899:8899?实际看 RAGFlow 默认容器内监听 80,但 8899:80 才是正确映射——不过更准确地说,它容器内是 80 端口,但配置里把容器内的 8899 映射到宿主机的变量,所以我把宿主端口设为 8899,容器端口不变)。我的最终配置是 SVR_WEB_HTTP_PORT=8899,对应映射 8899:8899?其实容器内是 80,但 .env 里 SVR_WEB_HTTP_PORT 是宿主机端口,容器内固定 80 吗?查了一下官方 docker-compose.yml,它是 "${SVR_WEB_HTTP_PORT}:80",所以这样改没问题。
改完后 docker compose down && docker compose up -d,这次容器跑起来了,没有端口冲突。
第五步:打开浏览器,迎来 502 Bad Gateway
容器全绿(docker compose ps 全 Up),访问 http://localhost:8899,满屏 502。Nginx 错误日志(容器内 /var/log/nginx/error.log)刷屏:
connect() failed (111: Connection refused) while connecting to upstream, client: 172.18.0.1, request: "GET /api/v1/users/me"
明明后端 9380 和 9381 端口都在,Nginx 却说连不上。
第六步:进容器探究竟,发现时间差谜团
我用 docker exec -it docker-ragflow-cpu-1 /bin/bash 进去,直接 curl -v http://localhost:9380/,居然返回了 {"code":404}——说明 9380 服务是活着的!那 Nginx 为什么报 refused?
翻看 docker logs docker-ragflow-cpu-1 --tail 200,发现了关键时间线:
- Nginx 日志里最早的
connect() failed时间戳是14:18 - 而应用日志里出现
Running on http://0.0.0.0:9380的时间是14:24:46 - 之间差了足足 6 分多钟!
也就是说:容器启动后,RAGFlow 的 API 服务需要将近 7 分钟才能完全初始化(加载模型、检查数据库、建表、加载插件)。在这段时间里,Nginx 已经启动并试图转发请求,自然连不上。
为什么初始化这么久?看启动日志里有大量 Loaded and normalized template file,还有 Init message_id sequence done,然后还有一行:
RAGFlow server is ready after 390.22442984580994s initialization.
390 秒,正好 6 分半。
第七步:解决方案 —— 等,就硬等
没有黑科技,就是等。在第一次 up -d 后,用 docker logs -f docker-ragflow-cpu-1 盯着,直到看到 RAGFlow server is ready after ... 这行,再刷新浏览器,页面秒开。
中间我犯了个错误:看到 502 就以为挂了,反复重启容器,导致初始化进程每次被打断,永远看不到 ready。后来耐着性子让它跑完,就成了。
第八步:登录 & 后续配置
浏览器输入 http://localhost:8899,出现登录页。默认账号 admin,密码 Infini@123(注意大小写)。登录后建议立刻改密码。
进入系统第一件事:配置大模型。在“设置”里填好 API Key 和 Base URL(我用的是 DeepSeek 的 API),不然上传文档后无法生成答案。
踩坑总览 & 经验
| 现象 | 根因 | 解决方案 |
|---|---|---|
| 镜像拉取超时 | 国内镜像源不稳定 | 换 DaoCloud/rainbond 源 |
| 80 端口绑定失败 | Windows HTTP.sys 占坑 | 改 .env 里的 SVR_WEB_HTTP_PORT 为 8899 |
| 502 持续数分钟 | 后端服务初始化慢,Nginx 过早代理 | 查看日志等待 ready 信息,或增加 proxy_connect_timeout(可选) |
| 容器内 curl 能通,Nginx 不通 | 时间错位,Nginx 是在服务未就绪时尝试的连接,之后缓存了失败状态 | 等待后重启 Nginx 或直接刷新 |
给后来者的几点建议
- 别急着刷页面:执行
docker compose up -d后,立刻docker logs -f盯着,看到ready再访问,能省一半折腾时间。 - 内存给足:RAGFlow + ES + MySQL + MinIO + Redis 全家桶,至少 16GB,否则 ES 会因内存不足退出。
- 端口规划:提前把 Web、API、Admin 端口在
.env里规划好,避免冲突。 - 生产环境:建议用
docker compose -f docker-compose-gpu.yml启用 GPU,或者单独拆数据库到外部。
最终状态
现在我的 RAGFlow 已经稳定跑了三天,传了几十份技术文档,Agent 串联了知识库检索和 LLM 回答,效果符合预期。整个部署过程虽然曲折,但把 Docker 网络、服务启动依赖、Nginx 反向代理这些点都摸了一遍,也算值了。
如果你也遇到 502,先别慌——去看看容器的日志,很多时候只是它还没准备好,而不是它坏了。
本文所有命令均在 Windows 11 + WSL2 (Ubuntu 22.04) + Docker Desktop 4.28 环境下验证。RAGFlow 版本 v0.27.0。
更多推荐

所有评论(0)