上一篇文章我对比了 几个开源知识库方案,最后选了 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 方式引入镜像。
需要下载的文件清单:
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 包里,系统默认没装。
修复:
RUNapt 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)。
修复:
RUNapt 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
修复:
RUNcurl -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 找不到(最诡异的一个)
报错:
ModuleNotFoundError: No 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.13venv 的 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 =====FROMbase AS productionUSERrootWORKDIR /ragflow# Install Python 3.13 (required by venv)RUNapt 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) ││ 向量检索引擎 │└─────────────────────────────────────────────────────────┘踩坑总结表
经验总结
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(爱)让生活更美好。如果你觉得我说的对,欢迎点赞收藏。
夜雨聆风