1 项目背景业务场景「云帆科技」CTO 在上周技术评审会上拍板先在本机搭建一套 RAGFlow 最小可用环境用真实的 HR 制度文档跑通全流程验证效果后决定是否全公司推广。运维工程师小李接到任务——用自己的开发笔记本16GB 内存、Windows 11 WSL2部署 RAGFlow。小李之前只玩过 nginx 和 MySQL 的单容器部署面对 RAGFlow 涉及的七八个服务API Server、Task Executor、MySQL、Redis、MinIO、Elasticsearch他心里没底这一堆服务怎么协调启动端口冲突了怎么办镜像拉不下来怎么办更让他头疼的是团队里有人用 macOS有人用 Linux还有人用 Windows每个人的环境都不一样。痛点在没有标准化部署方案的情况下服务依赖复杂RAGFlow 依赖数据库、缓存、对象存储、文档引擎手动一个个安装配置需要大半天还容易遗漏配置项。环境差异大Mac 上能跑的配置到 Windows 上就可能因为文件权限、路径分隔符、内存限制而失败。启动顺序敏感数据库没起来 ES 就启动会报错ES 没起来 RAGFlow 就启动会连不上——全靠人工判断。排障门槛高一个服务起不来新人不知道该看哪个日志、改哪个参数往往查了半天发现是vm.max_map_count没设。手动部署 RAGFlow 踩坑流程图 安装 MySQL → 配置用户/密码 → 安装 Redis → 安装 MinIO → 安装 ES ↓ ↓ ↓ ↓ ↓ 每个步骤都可能出错版本不兼容、端口冲突、权限不够、配置遗漏 ↓ 终于装完 → 启动 RAGFlow → 报错连不上 ES → 发现 ES 没启动 → 启动 ES ↓ 还是报错 → 查日志 2 小时 → 发现 vm.max_map_count 没改 → 终于成功2 项目设计小胖抱着笔记本跑过来“大师大师我昨天试着装 RAGFlowdocker compose up 一敲刷屏刷了十分钟最后一片红字——三个容器起不来这玩意儿也太难搞了吧”大师微微一笑“说说看哪三个容器起不来”小胖“Elasticsearch 报错 ‘max virtual memory areas vm.max_map_count [65530] is too low’MinIO 说端口 9000 被占用RAGFlow Server 说连不上数据库。我头都大了。”大师“这三个报错其实都是经典问题每个都有标准解法。先说你第一个——Elasticsearch 需要大量内存映射区域Linux 默认给的不够必须手动调大。”技术映射vm.max_map_count 内存地址空间的地图容量ES 需要把大量索引文件映射到内存地图太小就装不下。小白放下手中的茶“为什么 ES 需要那么多内存映射MySQL、Redis 怎么不需要设这个参数”大师“好问题。ES 底层是 Lucene它用 mmap 系统调用把磁盘上的索引文件映射到虚拟内存地址空间这样读写索引就像操作内存一样快。每个 Lucene segment 文件都需要映射加起来就能用掉几万个映射区。而 MySQL 用的是 Buffer Pool 自己管理缓存Redis 数据全在内存里它们不走 mmap 这条路自然不需要调这个参数。”小胖“哦所以不是 ES 矫情是它用了一种特殊的技术来加速查询。那我第二个问题端口冲突怎么办”大师“RAGFlow 的docker-compose.yml给每个服务分配了默认端口。但你的机器上可能已经有别的服务占用了。两种解法一是停掉冲突的本地服务二是改 RAGFlow 的端口映射。我推荐后者——修改项目根目录下的.env文件。”# .env 文件中的端口配置示例HTTP_PORT8080# 原默认 80改为 8080MINIO_PORT9001# 原默认 9000改为 9001ES_PORT9201# 原默认 9200改为 9201小胖“那数据库连不上又是怎么回事我明明看到 MySQL 容器是绿色的啊。”大师“这就是容器编排的经典问题——启动顺序。Docker Compose 默认按依赖关系启动但容器 ‘Started’ 不等于服务 ‘Ready’。MySQL 容器起来后内部的 mysqld 进程可能还需要 10-20 秒才能接受连接。RAGFlow Server 如果在 MySQL 准备好之前就连它自然失败。解决方案depends_on加condition: service_healthy配合healthcheck。”技术映射容器状态 绿灯亮进程在跑≠ 服务可用能响应请求就像餐厅开门了但厨师还没到岗。小白“那为什么不用 Kubernetes 一键部署呢还要自己调这么多参数”大师“K8s 确实能解决这些问题但对个人开发者和小团队来说太重了——你需要先搭 K8s 集群、配网络、设存储、搞 Ingress光是环境准备就要半天。Docker Compose 虽然简陋但五分钟就能拉起来适合入门和开发环境。K8s 部署我会在中级篇专门讲。”小白“还有个问题。RAGFlow 的 docker-compose-base.yml 和 docker-compose.yml 有什么区别为什么分两个文件”大师“这是精心设计的解耦。docker-compose-base.yml启动的是 RAGFlow 依赖的基础设施——MySQL、Redis、MinIO、Elasticsearch。docker-compose.yml启动的是 RAGFlow 自身服务——ragflow-server 和 task-executor。分两个文件的理由是”基础设施可复用如果你的 MySQL、Redis、ES 已经在别处运行了只需要启动 RAGFlow 自身的容器。独立扩缩容基础设施通常不频繁变动RAGFlow 应用服务可能频繁重启、升级、调试。安全隔离把有状态服务数据库和无状态服务应用分开管理减少误操作风险。技术映射基础设施 水电煤管道一次装修好不常动应用服务 家具电器经常换位置和升级。小胖“那 env 文件里那么多配置项哪些是必须改的哪些可以默认”大师“给新手一个最小配置清单”配置项是否必须改说明HTTP_PORT建议改默认 80 容易冲突MYSQL_PASSWORD必须改默认密码不安全MINIO_USER/MINIO_PASSWORD必须改对象存储凭证DOC_ENGINE低配必改内存 16GB 改为 infinityLLM_API_KEY建议填启动后可从控制台配置小白“最后一个问题。如果在 Windows 上跑有哪些额外的坑”大师“Windows 上的三大坑第一Docker Desktop 默认内存只有 2GB必须调到 16GB第二WSL2 里的vm.max_map_count每次重启会被重置需要加到.wslconfig第三文件路径不能有中文和空格项目目录最好放C:\projects\ragflow这样的纯 ASCII 路径下。”3 项目实战环境准备目标在一台 16GB 内存的开发机上完成 RAGFlow 全栈部署。硬件要求项目最低配置推荐配置CPU4 核8 核内存16GB32GB磁盘50GB 可用200GB SSD软件依赖Docker 24.0 Docker Compose v2Git 2.40Linux / macOS / Windows(WSL2)分步实现步骤1克隆代码并准备配置文件目标拉取 RAGFlow 源码生成.env配置文件。# 克隆仓库gitclone https://github.com/infiniflow/ragflow.git# 进入 docker 目录cdragflow/docker# 复制配置模板cp.env.example .env# 如果模板不存在参考 service_conf.yaml.template编辑.env文件调整必要配置# .env 最小化修改 HTTP_PORT8080 MYSQL_PASSWORDRagflow2024!Secure MINIO_USERragflow_admin MINIO_PASSWORDRagflow2024!Secure DOC_ENGINEinfinity # 低配机器用 infinity 替代 ES步骤2调整系统参数目标设置 Linux 内核参数确保 ES 或 Infinity 正常运行。# Linux / WSL2调整虚拟内存映射数sudosysctl-wvm.max_map_count262144# 永久生效Linuxechovm.max_map_count262144|sudotee-a/etc/sysctl.conf# Windows WSL2在用户目录下创建 .wslconfig# C:\Users\用户名\.wslconfig# [wsl2]# memory16GB# kernelCommandLine sysctl.vm.max_map_count262144坑点WSL2 重启后vm.max_map_count会重置。务必写入.wslconfig文件或者每次重启后手动执行。步骤3启动基础服务目标启动 MySQL、Redis、MinIO、文档引擎。# 在 ragflow/docker 目录下执行dockercompose-fdocker-compose-base.yml up-d# 检查所有容器状态STATUS 应为 Up 或 healthydockercompose-fdocker-compose-base.ymlps预期输出NAME STATUS ragflow-mysql-1 Up (healthy) ragflow-redis-1 Up (healthy) ragflow-minio-1 Up (healthy) ragflow-es-1 Up (healthy) # 或 ragflow-infinity-1坑点ES 容器状态显示healthy可能需要 30-60 秒因为它内部有健康检查脚本。如果一直unhealthy执行docker logs ragflow-es-1查看原因。常见原因vm.max_map_count未设置、磁盘空间不足。步骤4启动 RAGFlow 主服务目标启动 API Server 和 Task Executor。# 启动 RAGFlowdockercompose-fdocker-compose.yml up-d# 等待约 30 秒后检查状态dockercompose-fdocker-compose.ymlps# 查看启动日志确认无错误dockercompose logs ragflow-server|tail-20dockercompose logs ragflow-task-executor|tail-20预期日志ragflow-server 启动成功[INFO] Starting RAGFlow API Server... [INFO] Database connected: mysql://ragflow:***mysql:3306/ragflow [INFO] Redis connected: redis://redis:6379/0 [INFO] MinIO connected: http://minio:9000 [INFO] API Server listening on 0.0.0.0:9380步骤5验证部署目标确认所有服务可用。# 1. 验证 Web 控制台curl-Ihttp://localhost:8080# 预期HTTP/1.1 200 OK# 2. 验证 APIcurlhttp://localhost:8080/api/v1/version# 预期{code: 0, data: {version: 0.26.0}}# 3. 验证 MySQLdockerexecragflow-mysql-1 mysql-uroot -p${MYSQL_PASSWORD}-eSELECT VERSION();# 4. 验证 Redisdockerexecragflow-redis-1 redis-cli PING# 预期PONG# 5. 验证 MinIOcurlhttp://localhost:9001/minio/health/live# 预期HTTP/1.1 200 OK# 6. 验证文档引擎Infinitydockerexecragflow-infinity-1curl-shttp://localhost:23820/admin/node/status步骤6初始化登录与配置目标完成首次登录和基本配置。浏览器访问http://localhost:8080用默认账号登录adminragflow.io/ragflow立即修改密码「系统设置」→「修改密码」点击「系统设置」→「模型供应商」添加至少一个 LLM如 OpenAI 兼容接口添加至少一个 Embedding 模型# 通过 API 添加模型供应商以 OpenAI 兼容接口为例curl-XPOST http://localhost:8080/api/v1/llm\-HAuthorization: Bearer your-token\-HContent-Type: application/json\-d{ llm_factory: OpenAI, api_key: sk-your-key-here, base_url: https://api.openai.com/v1, model_type: chat }测试验证# 端到端冒烟测试脚本#!/bin/bashBASE_URLhttp://localhost:8080# 1. 健康检查echo 1. 健康检查 curl-s-o/dev/null-w%{http_code}$BASE_URLecho# 2. 登录获取 Tokenecho 2. 登录 TOKEN$(curl-s-XPOST $BASE_URL/api/v1/login\-HContent-Type: application/json\-d{email:adminragflow.io,password:ragflow}\|jq-r.data.access_token)echoToken:${TOKEN:0:20}...# 3. 创建数据集echo 3. 创建数据集 DATASET$(curl-s-XPOST $BASE_URL/api/v1/datasets\-HAuthorization: Bearer$TOKEN\-HContent-Type: application/json\-d{name:冒烟测试数据集-}$(date%s)})echo$DATASET|jq.data.name# 4. 列出数据集echo 4. 列出数据集 curl-s$BASE_URL/api/v1/datasets\-HAuthorization: Bearer$TOKEN\|jq.data | lengthechoecho 冒烟测试完成 预期结果所有步骤返回正常状态码和数据无报错。完整代码清单Git 仓库https://github.com/infiniflow/ragflowDocker 部署配置docker/docker-compose.yml、docker/docker-compose-base.yml配置文件模板docker/.env.example、docker/service_conf.yaml.template4 项目总结优点 缺点维度Docker Compose 部署手动源码部署K8s 部署部署速度★★★ 5 分钟★☆☆ 1-2 小时★★☆ 30 分钟含模板环境一致性★★★ 镜像保证★☆☆ 依赖版本差异★★★ 容器标准化资源占用★★☆ 约 12GB★★★ 按需分配★☆☆ 额外 K8s 开销调试便利★★☆ 需 exec 进容器★★★ 本地直接调试★★☆ 需端口转发生产就绪★★☆ 单机可用★☆☆ 缺乏治理★★★ 企业级学习成本★★★ 低★★☆ 中等★☆☆ 较高适用场景个人学习与开发在一台机器上快速体验 RAGFlow 全部功能适合本章场景。POC 验证给领导演示、给团队评估快速出结论。小型团队试用5-10 人的小团队内部试用文档量在 1000 份以内。CI/CD 测试环境在流水线中自动拉起 RAGFlow 环境跑集成测试。离线环境部署提前下载镜像复制到内网机器一键启动。不适用场景大规模生产环境单机无法承受高并发且无高可用保障。多租户隔离需求Docker Compose 无法做到租户级的资源隔离和网络策略。注意事项密码安全.env中的MYSQL_PASSWORD、MINIO_PASSWORD绝对不能提交到 Git。建议使用.env.local覆盖或 CI/CD 变量注入。数据卷持久化Docker Compose 默认使用命名卷存储数据。如果要迁移需要了解docker volume的备份和恢复。内存不足的降级方案如果机器只有 8GB 内存除了把 DOC_ENGINE 改为 infinity还需要降低 MySQL 和 ES 的内存限制在 compose 文件中修改mem_limit。安装过程中 RAGFlow 服务日志无输出检查service_conf.yaml.template是否在 docker 目录下RAGFlow 启动会读取它。Infinity 替代 ES 后的限制Infinity 不支持部分 ES 的高级查询语法如果后续用到复杂检索可能需要切回 ES。常见踩坑经验故障现象根因解决方法docker compose up卡住不动Docker 镜像拉取慢或网络超时配置镜像加速器或手动docker pull每个镜像ES 反复unhealthyvm.max_map_count不足或磁盘空间不够sysctl -w vm.max_map_count262144df -h检查磁盘RAGFlow Server 启动后立刻退出数据库连接失败或service_conf.yaml.template缺失docker logs ragflow-server查看具体错误MinIO 端口被占用本地已有 MinIO 或其他服务用了 9000/9001修改.env中的 MinIO 端口映射浏览器访问 8080 端口空白页前端静态资源未正确加载等待服务完全启动后再刷新或检查前端容器日志思考题Docker Compose 的depends_on只能保证容器启动顺序不能保证服务就绪。请设计一个方案不借助外部工具确保 RAGFlow Server 在 MySQL 真正可用后才开始初始化数据库连接。如果你的团队决定将 RAGFlow 部署到没有互联网的内网环境请列出需要提前准备的所有 Docker 镜像和离线依赖并设计镜像导出/导入的操作步骤。答案提示见第3章末尾或附录 D。延伸阅读与资源10倍开发者的 Dify 魔法书从零构建全栈 AI 应用后端工程师转型AI第一课-Ollama 与私有化大模型实战大型语言模型(LLM) vLLM 高性能推理落地实战Agent开发之LlamaIndex 实战修炼与源码进阶大语言模型Transformers 实战修炼与源码剖析