乐于分享
好东西不私藏

在ARM服务器上部署RAGFlow,从源码编译到12 次 Docker 构建,5 小时才完成

在ARM服务器上部署RAGFlow,从源码编译到12 次 Docker 构建,5 小时才完成

上一篇文章我对比了 几个开源知识库方案,最后选了 RAGFlow——一个官方不支持 ARM64 的。

你可能想问:明知不支持,为什么不换一个?

因为 RAGFlow 的文档解析能力,真的碾压其他方案。它不只是提取文字,而是能识别表格、图片、公式、版面结构,按语义智能分段,支持的文件类型是最广的,而且所说内容准确度也是最高手的,再加上Deerflow默认就支持

就像一个读过书的人帮你整理笔记,而不是把书撕成碎片让你自己拼。

既然不能直接下载官方的镜像拉起来,所以我决定:从源码编译,让它在鲲鹏 920 上跑起来。

这一编译,就是 5 个小时,12 次 Docker 构建迭代。

第一幕:发现" exec format error"

一切从一条报错开始。

我在  服务器上执行:

docker pull infiniflow/ragflow:v0.26.0
docker compose up -d

然后看到:

Error: exec format error

翻译成人话:这个镜像是给 Intel/AMD 芯片编译的,你的鲲鹏 ARM64 芯片看不懂

我查了一下官方文档,只写了 linux/amd64,没有 linux/arm64。

不死心,又去 GitHub Issues 搜了搜,发现有人提过 ARM64 支持的需求,官方回复"暂无计划"

那就只有一个办法:自己从源码编译。

第二幕:源码获取——GitHub 连不上

 服务器访问 GitHub,超时。

GnuTLS recv error (-110): The TLS connection was non-properly terminated.

换 本机试了试,也超时。

GitHub 就是连不上。

怎么办?用代理。

我发现有个叫 ghfast.top 的 GitHub 镜像代理,把 URL 里的“https://github.com”换

 “https://ghfast.top/https://github.com” 就行。

git clone https://ghfast.top/https://github.com/infiniflow/ragflow.git

成功了!源码 500 多 MB,下载了 10 分钟。

然后 scp 通过本地传输到要部署的 服务器:

scp -r ragflow/ wader@192.168.100.239:/home/wader/ragflow/src/

第一个坑出现了:scp 传输经常"假成功"。

命令执行完了,没有报错,但到远程 上一看,文件还是旧的。

试了三次,换了两种写法,最后用管道方式才成功:

tar czf - ragflow/ | ssh user@192.168.1.200 "tar xzf - -C /home/user/ragflow/src/"

教训:scp 经常假成功,用 tar + ssh 管道更可靠。

第三幕:依赖文件下载——到处都是FW

RAGFlow 的 Dockerfile 里有很多 wget 命令,要从各种网站下载依赖文件。

我预感这些下载在构建时会超时,所以决定提前下载好,用 COPY 方式引入镜像。

需要下载的文件清单:

文件
大小
来源
问题
deepdoc 模型
322MB
hf-mirror.com
✅ 顺利
text_concat_xgb 模型
-
hf-mirror.com
✅ 顺利
cl100k_base.tiktoken
1.68MB
openaipublic.azureedge.net
✅ 顺利
UV (aarch64)
20MB
ghfast.top
✅ 顺利
libssl1.1 (arm64)
1.2MB
ports.ubuntu.com
✅ 顺利
en_core_web_sm
12.5MB
ghfast.top
⚠️ GitHub 代理,需要替换 URL
Tika
78MB
archive.apache.org
❌ 卡住了

Tika 是个大坑。

archive.apache.org 在中国访问极慢,本机下载到 78MB 成功了,但 scp 传输到 远程 又是"假成功"。

远程 自己下载,速度只有 ~1MB/min,下载到 65MB 就卡住了。

等了 20 分钟,还是 65MB。

最后决定:跳过 Tika,用已有的 65MB 文件。

后来发现 Tika 是可选的,不影响核心功能。

教训:预下载依赖文件,不要在 Dockerfile RUN 中 wget。网络环境比你想象的更差

第四幕:Dockerfile 适配——7 个致命问题

拿到源码和依赖文件后,开始写 Dockerfile。

RAGFlow 的原始 Dockerfile 是给 x86 设计的,需要做以下适配:

1. Chrome/Chromedriver:用系统 chromium-browser 替代

2. Python 3.13:Ubuntu 24.04 自带 3.12,需要从 deadsnakes PPA 安装

3. 编译工具链:C 扩展需要 build-essential、zlib1g-dev 等

4. Node.js:前端构建需要 npm

5. Infinity 向量库:不支持 ARM64,改用 Elasticsearch

6. GitHub 依赖:用 ghfast.top 代理

7. apt/pip 镜像源:用阿里云加速

看起来不难对吧?

然后我开始构建,连续失败了 12 次。

第五幕:12 次构建迭代——每次都是新坑

第 1-3 次:Python 3.13 安装失败

报错:

add-apt-repository: command not found

排查过程:

1. 检查Dockerfile,add-apt-repository ppa:deadsnakes/ppa -y 2>/dev/null || true

2. 发现 2>/dev/null || true 把错误信息静默了

3. 去掉静默,看到真实报错:

add-apt-repository: command not found

根因:add-apt-repository 命令在 software-properties-common 包里,系统默认没装。

修复:

RUN apt update && apt install -y software-properties-common gpg && \    add-apt-repository ppa:deadsnakes/ppa -y && \    apt update && \    apt install -y python3.13 python3.13-dev python3.13-venv

教训:在 Dockerfile 里,永远先装依赖再用命令。不要用 2>/dev/null || true 静默错误

第 4-5 次:编译 C 扩展失败

报错:

zlib.h: No such file or directory

排查过程:

1. 查看报错的包:zlib-state

2. 这是一个需要编译 C 代码的 Python 包

3. 缺少 zlib 的开发头文件

根因:系统只装了 zlib 的运行时库(zlib1g),没装开发包(zlib1g-dev)。

修复:

RUN apt update && apt install -y build-essential gcc g++ \    zlib1g-dev libffi-dev libssl-dev

教训:从源码编译,所有 C 语言依赖的开发包都得装。x86 镜像里已经装好了,但从源码编译得自己搞定

第 6-7 次:GitHub 依赖下载超时

报错:

Failed to download en_core_web_sm from https://github.com/explosion/spacy-models/...

排查过程:

1. en_core_web_sm 是 spaCy 的英文模型,从 GitHub 下载

2. 远程 服务器连不上 GitHub

3. uv.lock 里的 URL 都是 https://github.com/...

修复:一行 sed 命令替换所有 GitHub URL:

RUN sed -i 's|https://github.com|https://ghfast.top/https://github.com|g' uv.lock

教训:搞开源项目,GitHub 代理是刚需。uv.lock 里的 URL 可以批量替换

第 8-9 次:npm 命令不存在

报错:

npm: command not found

排查过程:

1. 前端构建需要 npm,但 Dockerfile 里没装 Node.js

2. 原始 Dockerfile 假设 builder 阶段已经有 npm,但我们的基础镜像是 ubuntu:24.04

修复:

RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && \    apt install -y nodejs

教训:前端构建需要 Node.js,别忘了。

第 10 次:VERSION 文件缺失

报错:

cat: /ragflow/VERSION: No such file or directory

排查过程:

1. 容器启动时,entrypoint 脚本需要读取 VERSION 文件

2. VERSION 文件在 builder 阶段创建了

3. 但 production 阶段没有复制过来

修复:

COPY --from=builder /ragflow/VERSION /ragflow/VERSION

教训:多阶段构建时,要注意文件是否从 builder 阶段复制到了 production 阶段

第 11 次:nginx 配置文件名不匹配

报错:

cp: cannot stat '/etc/nginx/conf.d/ragflow.conf.python': No such file or directory

排查过程:

1. Dockerfile 里把 ragflow.conf.python 复制成了 ragflow.conf

2. 但 entrypoint 脚本还需要原文件名 ragflow.conf.python

3. entrypoint 脚本会根据环境变量选择复制哪个配置文件

修复:同时复制两个文件名:

COPY docker/nginx/ragflow.conf.python /etc/nginx/conf.d/ragflow.confCOPY docker/nginx/ragflow.conf.python /etc/nginx/conf.d/ragflow.conf.python

教训:Dockerfile 里的 COPY 和 entrypoint 脚本的逻辑要对齐。改名前先看看 entrypoint 怎么用的

第 12 次:quart_auth 找不到(最诡异的一个)

报错:

ModuleNotFoundErrorNo module named 'quart_auth'

排查过程:

这一个坑,我花了半小时才找到根因。

首先,我进入容器检查:

docker exec ragflow-cpu bash -c 'ls /ragflow/.venv/lib/python3.13/site-packages/ | grep quart'

输出:

quart_auth

quart_auth 明明装了,为什么 Python 找不到?

继续排查:

docker exec ragflow-cpu bash -c 'which python3; python3 --version'

输出:

/usr/bin/python3Python 3.12.3

Python 版本是 3.12,不是 3.13!

再查 venv 的 python:

docker exec ragflow-cpu bash -c 'ls -la /ragflow/.venv/bin/python*'

输出:

/ragflow/.venv/bin/python3 -> /usr/bin/python3.13

venv 的 python 链接到 /usr/bin/python3.13,但这个文件不存在!

因为 production 阶段只装了系统自带的 Python 3.12,没装 3.13。

venv 在 builder 阶段用 Python 3.13 创建,但到了 production 阶段,Python 3.13 不存在了,venv 的 python 无法执行。

翻译成人话:你在 Windows 11 上装了个软件,但运行时系统认为自己是 Windows 10,找不到对应的运行库。

修复:在 production 阶段也安装 Python 3.13:

# ===== production stage =====FROM base AS productionUSER rootWORKDIR /ragflow# Install Python 3.13 (required by venv)RUN apt update && apt install -y software-properties-common gpg && \    add-apt-repository ppa:deadsnakes/ppa -y && \    apt update && \    apt install -y python3.13 python3.13-dev python3.13-venv && \    rm -rf /var/lib/apt/lists/*

教训:Dockerfile 多阶段构建时,production 阶段必须包含 venv 需要的 Python 版本。venv 里的 python 链接是硬编码的。

第六幕:Elasticsearch 镜像拉取——Docker Hub 也超时

RAGFlow 需要向量数据库。Infinity 不支持 ARM64,改用 Elasticsearch 8.11.3

docker pull elasticsearch:8.11.3

超时。

再试,还是超时。

Docker Hub 连不上。怎么办?用国内镜像。

docker pull docker.m.daocloud.io/elasticsearch:8.11.3docker tag docker.m.daocloud.io/elasticsearch:8.11.3 elasticsearch:8.11.3

1 秒完成。

教训:Docker Hub 拉不动时用 daocloud 镜像。还有 1ms.run、dockerhub.icu 等备选

第七幕:启动验证——175 秒的等待

所有问题都修复后,终于到了启动验证的时刻。

docker compose up -d es01 ragflow-cpu

然后等。

docker logs -f ragflow-ragflow-cpu-1

看到一堆日志在滚动:

Starting ragflow_server...Starting nginx...Creating tables in rag_flow database...

等了 175 秒,终于看到:

RAGFlow server is ready after 175.10713124275208s initialization.Running on http://0.0.0.0:9380

成功了!

验证 WebUI:

curl -s http://localhost:80 | head -5

返回 HTML 内容,HTTP 200。

验证 API:

curl -s http://localhost:9380/api/status

返回 JSON 状态信息。

5 个小时,12 次构建迭代,7 个关键修复,终于跑起来了。

最终架构

┌─────────────────────────────────────────────────────────┐│                    239 服务器 (鲲鹏 920)                 │├─────────────────────────────────────────────────────────┤│  ragflow-cpu (80/9380)                                  ││    ├── nginx (反向代理)                                  │    ├── ragflow_server (Python 3.13)                     ││    └── task_executor (文档解析/向量化)                   │├─────────────────────────────────────────────────────────┤│  MySQL (13306)     Redis (6379)     MinIO (9000/9001)   ││  存储元数据          缓存/队列        文件存储            ├─────────────────────────────────────────────────────────┤│  Elasticsearch 8.11.3 (1200)                            ││  向量检索引擎                                            │└─────────────────────────────────────────────────────────┘

踩坑总结表

问题
根因
解决方案
耗时
Python 3.13 安装失败
缺少 software-properties-common
先装依赖再加 PPA
20min
zlib.h 缺失
缺少 zlib1g-dev
安装完整编译工具链
15min
GitHub 依赖超时
 无法直连 GitHub
用 ghfast.top 代理
10min
npm 命令不存在
未安装 Node.js
安装 Node.js 20 LTS
5min
VERSION 文件缺失
未 COPY 到 production 阶段
添加 COPY 指令
5min
nginx 配置文件名不匹配
entrypoint 需要原文件名
同时复制两个文件名
10min
quart_auth 找不到
production 阶段 Python 版本不对
在 production 阶段也装 Python 3.13
30min
ES 镜像拉取超时
Docker Hub 访问慢
用 daocloud 镜像
5min

经验总结

1. Dockerfile 多阶段构建时,production 阶段必须包含 venv 需要的 Python 版本

2. 预下载依赖文件用 COPY 引入,不要在 RUN 中 wget

3. 构建前检查 .dockerignore 是否排除了需要的文件

4. 调试容器启动失败时,用 --entrypoint sleep 挂起容器以便 exec

5. Docker Hub 拉不动时用国内镜像(daocloud、1ms.run)

6. GitHub 访问困难时用 ghfast.top 代理

7. scp 传输经常假成功,用 tar + ssh 管道更可靠

8. 不要用 2>/dev/null || true 静默 Dockerfile 中的错误

写在最后

有人问我:花 5 个小时编译一个软件,值得吗?

我的回答是:如果你只是想"能用",不值得。但如果你想"用好",值得。

RAGFlow 的文档解析能力,从参数上来看,真的和其他方案不是一个量级,此前我用过dify的rag,也用过weknora的rag,后续我用了再来写篇文章做个测评。

而且这个过程让我对 Dockerfile、多阶段构建、Python 虚拟环境有了更深的理解。

有时候,踩坑也是一种学习。

如果你也在 ARM64 服务器上部署过软件,欢迎在评论区分享你的踩坑经历。

最后部署的界面如下:


我是AI易用君,在此公众号分享探索、学习、使用AI的经验,让我们一起来学AI,用AI,AI(爱)让生活更美好如果你觉得我说的对,欢迎点赞收藏。