最近在帮团队搭内部知识库,同事丢给我一个我此前没太关注过的开源项目WeKnora。简单说,它是一套基于RAG技术的开源知识库问答系统,把PDF、Word、Markdown这些文档传进去,系统自动完成切片、向量化和索引,再接上大语言模型,就能用自然语言直接提问,而且答案能追溯到原文出处。我试用之后最大的感受是,它正好切中了团队“文档越来越多、找东西越来越难”的痛点。考虑到它涉及到的组件比较多,我最终选择用Docker Compose整体部署,前后跑了小半天,中间踩了不少坑。这篇文章就把我的部署过程、配置解析和排错经验完整写出来,给想快速上手WeKnora的朋友一个参考。
1. WeKnora到底是什么
1.1 一条典型的RAG知识库处理链路
要搞懂WeKnora能做什么,先要理解RAG。RAG的全称是Retrieval-Augmented Generation,意思是“检索增强生成”。传统的大模型对话,靠的是模型在训练阶段学到的知识,你问它一个私有的、没有训练过的内容,它要么说不知道,要么一本正经地编。RAG的思路则完全不同:先把私有文档切块、向量化、建索引;用户提问时,先到索引里把最相关的几段内容检索出来;最后把问题和检索结果一起交给大模型,让大模型基于这些材料组织答案。
WeKnora把这套RAG链路完整地产品化了。文档进入系统后,会经过解析、清洗、切片、向量化、写入向量数据库这几个阶段。WeKnora本身不负责向量化和模型推理,它通过配置和接口把嵌入模型、向量数据库、大模型串起来,相当于一个“编排者”和“交互前端”的结合体。这也是我一开始容易混淆的地方——如果需要它具备完整的问答能力,你不光要部署WeKnora,还得给它配上模型服务和向量数据库。
1.2 它适合解决什么问题
我梳理了一下,最适合WeKnora的几类场景:
- 企业内部知识库:操作手册、规章制度、FAQ散落在各处,新人问问题没人带,可以让WeKnora把文档变成可查询的问答入口。
- 个人资料整理:把读书笔记、收集的干货文章统一管理,之后用问答方式调取。
- RAG技术学习和二次开发:WeKnora提供了一个开箱即用的界面和API,适合研究整套RAG流程,甚至可以改代码做定制。
这里要特别提醒一句:WeKnora不是搜索引擎,也不是通用助手。它的强项是针对“文档集合”的精准问答,答案可以溯源;它的弱点是如果文档本身没有相关内容,它会诚实地说不知道,或者给出基于可检索资料的有限回答。理解这一点,你对它的期望值会比较合理。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 为什么选择Docker Compose部署
2.1 组件多、依赖复杂,手工部署代价大
WeKnora的部署不是解压一个二进制包那么简单。它需要前端静态资源、后端API服务、任务队列、向量数据库和模型服务协同工作。如果直接部署在裸机上,你可能要先折腾一遍Node/Python环境、系统依赖库、数据库安装、端口管理,每台机器都来一遍,非常折磨人。更麻烦的是,升级时旧环境残留容易留下各种“我这能跑,你那不能跑”的历史难题。
Docker Compose的核心价值是把“环境”变成代码。所有组件被定义成容器服务,服务之间的网络、数据持久化、环境变量、依赖顺序都在一份YAML文件里声明。部署新机器时,拷贝目录、执行docker compose up -d,整套环境就起来了。这对团队协作、测试环境复制都有非常明显的效率提升。
我去年帮另一个项目部署过一套类似的知识库方案,当时没有用容器,所有组件都手动装。光是数据库版本和系统库的兼容问题就排查了快两天。后来换了一台新机器,同样的问题又冒出来。用Compose之后,同样的场景只需要把配置文件拷过去,一条命令搞定。所以如果你问我,团队规模再小,我也建议容器化起步。环境统一了,后续升级、回滚都简单;我可以随时切换镜像tag来做版本对比,这比在裸机上维护一堆进程要省心得多。
2.2 数据卷挂载与网络隔离设计
Compose还提供网络隔离能力。默认情况下,WeKnora、向量数据库和模型服务在同一个内部网络中,别的容器和外部网络无法随意访问这些服务。我通常只把Web界面端口映射到宿主机,向量数据库和模型服务的端口根据调试需求决定是否对外。数据方面,采用宿主机目录挂载或命名数据卷,容器销毁后数据依然存在,备份时直接打包对应目录即可。
坦白说,用Docker部署也有学习门槛。至少你要理解镜像、容器、数据卷、端口映射这几个概念。但如果只是想用WeKnora,而不是研究容器底层原理,Compose就是最容易入门的方案了。拿到官方提供的编排示例后,基本就是“抄作业”级别,按着改一改就能跑起来。
2.3 先拆解服务结构再动手
我拿到部署方案之后并没有马上启动,而是先拆解了它的服务结构:哪些是必须的、哪些是可选的。比如向量数据库是必须的,因为没有它,文档向量无处存放;模型服务可以本地部署也可以用远程API;如果只是试用,可以先不接额外业务数据库,把元数据放在本地即可。这种“先拆再装”的习惯能帮你控制风险,出了问题也知道该查哪个服务。
3. 部署前的准备工作
3.1 硬件配置参考
先聊硬件。很多人对知识库系统的资源需求没有概念。我的实测结论是:WeKnora主服务本身占用资源不高,内存大头在模型服务和向量数据库。
- 最小配置(接云端API):4核CPU、8GB内存,磁盘40GB。适合文档量不大的试验环境。
- 推荐配置(本地7B级别模型):8核CPU、16GB内存,磁盘80GB。能够流畅运行量化版7B模型,并支持中等规模的文档库。
- 舒适配置(需要更高并发):16核CPU、32GB内存,磁盘120GB以上,最好有8GB以上显存的GPU用于模型推理。
我的实际环境是32GB内存的服务器,同时运行WeKnora、Qdrant和7B量化模型,整套系统内存占用大约14GB。如果你要跑更大的模型,或者在向量数据库里存上百万条向量,建议照着舒适配置来。GPU并不是必须的,但如果有GPU,本地模型的推理速度会明显更快。没有GPU时CPU推理也能用,只是回答等待时间会拉长,体验稍差。
3.2 Docker环境检查
安装Docker是前置条件。检查一下版本:
bash复制docker --version
docker compose version
我建议Docker版本不低于20.10,Compose使用V2版本。如果你的服务器上只有旧的docker-compose独立命令,建议升级到新版Docker自带的Compose插件,因为旧的独立版本在某些发行版上是Python脚本,语法和网络处理方式都有些差异。确认没问题之后再继续。
3.3 镜像加速与拉取准备
WeKnora相关镜像主要来自Docker Hub。国内网络环境下,拉取有时会很慢甚至失败。我的做法是配置registry mirror加速。具体来说,编辑Docker守护进程配置文件,加入你所在云厂商提供的加速地址,然后重载Docker服务。
bash复制sudo systemctl daemon-reload
sudo systemctl restart docker
配置好之后,先手动拉取基础镜像,验证网络是否通畅。这一步放在部署之前,能提前暴露网络问题,避免部署流程走到一半卡住。
4. docker-compose.yml配置与启动实操
4.1 部署目录规划
动手前先规划目录。我通常会创建一个独立的部署目录,把所有数据和配置都收拢在里面:
code复制weknora-deploy/
├── docker-compose.yml
├── .env
├── data/
├── qdrant_storage/
└── ollama_models/
目录规划的意义在于备份和迁移。你只要整体打包weknora-deploy目录,就相当于把整套应用的数据和配置备份了下来。换机器的时候解压到新位置,执行compose up,环境就回来了。
4.2 一份可用的docker-compose.yml样例
基于我的部署实践,这里给出一份涵盖三个核心服务的compose文件。镜像版本请以你实际使用的版本为准,我这里用latest做演示:
yaml复制version: "3.8"
services:
weknora:
image: weknora/weknora:latest
container_name: weknora
restart: unless-stopped
ports:
- "8080:8080"
environment:
- DB_TYPE=qdrant
- QDRANT_HOST=qdrant
- QDRANT_PORT=6333
- LLM_BASE_URL=http://ollama:11434
- LLM_MODEL=qwen2.5:7b
- EMBEDDING_BASE_URL=http://ollama:11434
- EMBEDDING_MODEL=bge-m3
volumes:
- ./data:/app/data
depends_on:
- qdrant
- ollama
networks:
- weknora-net
qdrant:
image: qdrant/qdrant:latest
container_name: weknora-qdrant
restart: unless-stopped
ports:
- "6333:6333"
volumes:
- ./qdrant_storage:/qdrant/storage
networks:
- weknora-net
ollama:
image: ollama/ollama:latest
container_name: weknora-ollama
restart: unless-stopped
ports:
- "11434:11434"
volumes:
- ./ollama_models:/root/.ollama
networks:
- weknora-net
networks:
weknora-net:
driver: bridge
4.3 关键配置逐项解析
YAML配置容易看懂,但有几个坑必须说明。
第一,WeKnora访问模型服务的地址,在容器内一定要写服务名。比如Ollama服务名是ollama,那么LLM_BASE_URL里就应该写http://ollama:11434,不能写http://localhost:11434。这个问题我见过很多人栽跟头,因为从宿主机视角看,localhost就是本机,但从容器视角看,localhost指向的是容器自己,根本访问不到宿主机上的Ollama。
第二,depends_on只控制依赖服务的启动顺序,但不等服务真正就绪。我的经验是,启动命令里先单独启动依赖服务,过几秒再启动WeKnora,成功率更高。如果整体一条命令启动后出现连接失败,可以稍等片刻再执行docker compose restart weknora。
第三,环境变量名以官方文档为准。我示例里的变量名(DB_TYPE、LLM_BASE_URL等)代表了这一类配置的通用写法,但不同版本可能有差异。部署之前先把当前版本的配置变量对照表看一眼,能省不少事。
4.4 启动与验证
配置好之后按顺序启动:
bash复制docker compose up -d qdrant ollama
sleep 5
docker compose up -d weknora
docker compose ps
查看所有容器均为Up状态后,访问http://宿主机IP:8080。如果页面能正常打开,说明主服务正常。如果打开后空白或报错,先看日志:
bash复制docker compose logs -f weknora
日志是排查问题的第一入口,很多配置错误都会在这里暴露。
5. 模型服务接入与知识库建立
5.1 大模型服务两种选择
WeKnora本身不自带模型,需要接入一个大模型服务。结合我自己的使用经验,有两种方案比较可行。
第一种是接本地模型。通过Ollama运行开源模型,优点是数据不出内网,隐私可控;缺点是需要占用本地资源,模型质量相比商用API有差距。我内部环境用的就是Ollama加7B量化模型。
第二种是接云端API。如果文档不敏感,只是为了快速验证效果,可以直接在管理界面填入云端API的地址、密钥和模型名。优点是省资源、模型能力强,缺点是数据不可控。
我的建议:如果是个人学习或非敏感知识库,先接云端API把流程跑通;如果是企业私密文档,老老实实本地模型。无论哪种方案,模型服务起来之后,都要在WeKnora界面里把模型名称填对,这一步直接影响后续问答质量。
5.2 嵌入模型与向量化
嵌入模型负责把文本变成向量,它的质量和文档语言类型直接相关。中文场景下,优先选中文优化的嵌入模型。我在部署时踩过一个坑:初始用了通用嵌入模型,检索中文文档的准确率很一般,换到中文优化模型后效果立刻改善。如果你的知识库以英文为主,选择逻辑类似。
使用Ollama作为嵌入服务时,需要先拉取对应的嵌入模型:
bash复制docker exec -it weknora-ollama ollama pull bge-m3
WeKnora管理界面里填写嵌入模型的名称和接口地址,如果嵌入服务也容器化了,地址同样要写成容器服务名。向量数据库这里我选了Qdrant,理由是它在Docker化部署上最省心,单机模式不需要其他依赖。如果用Milvus,还需要Etcd、MinIO等组件,虽然功能更强,但对部署复杂度要求也高一些。中小规模知识库选Qdrant完全够用。
5.3 创建知识库并完成问答测试
模型和服务都就绪后,进入管理界面创建知识库。上传几份自己手边的典型文档,比如Markdown格式的操作手册、PDF制度的公告。上传后系统开始解析和向量化,文档多的话需要一些时间,但都会有进度提示。
我在测试时上传了三份操作手册,索引完成大概用了不到十分钟。随后在问答界面输入问题,系统返回的回答带着引用来源,点击来源可以直接跳到原文段落。这个设计让我印象很深——RAG问答不只是给你一个答案,而是给出答案的依据。对内部知识库场景来说,溯源能力比模型本身更强更重要。
6. 常见问题与排查技巧实录
6.1 页面无法访问:端口与防火墙
页面打不开,第一反应查端口。用ss命令确认一下:
bash复制ss -tlnp | grep 8080
如果端口被其他进程占用,改compose里的映射端口。如果端口正常,检查宿主机防火墙和云服务器安全组,确认放行了对应端口。很多云服务器的坑都在安全组规则上,本地监听再正常,安全组不放行也是白搭。
6.2 模型服务连接失败
WeKnora日志里如果出现连接模型服务超时的报错,基本就是网络地址问题。最典型的错误是容器内部使用了localhost去访问宿主机服务。服务之间通信必须用Compose网络的服务名。
如果确认服务名没错,再用exec进容器测试连通性:
bash复制docker exec -it weknora curl http://ollama:11434
能返回模型服务响应,说明网络正常;不能返回则多半是Ollama服务没起来或端口不对。
6.3 内存不足导致OOM
本地模型加载时内存不足,严重时容器直接被杀。查看系统日志里会有Killed字样。解决办法有几个方向:换更小的量化模型、给系统增加swap、或者减小向量数据库的缓存配置。我建议先加swap,成本最低,能让系统在内存吃紧时不会立刻崩。
6.4 检索问答效果不理想
问答不准确,问题很可能出在嵌入模型或切片参数上。切片太长导致噪声过多,片段之间失去语义独立性;切片太短则上下文不全,模型难以理解。我常用的切片参数是块长300到500字符,重叠50字符。不同文档类型可以微调,Markdown和PDF的处理逻辑也有差别。
6.5 常见故障速查表
| 症状 | 可能原因 | 快速处理 |
|---|---|---|
| 页面打不开 | 端口冲突或防火墙 | 检查端口监听与安全组 |
| 模型连接超时 | 地址写成localhost | 改为容器服务名 |
| 容器反复重启 | 配置格式错误或OOM | 查看日志,检查内存 |
| 知识库上传失败 | 文件格式不支持 | 转换格式后重试 |
| 回答引用错误 | 切片策略不合理 | 调短切块长度 |
7. 部署后的日常维护与备份
7.1 数据备份与恢复
知识库最有价值的数据是向量数据库和文档索引。Qdrant的数据挂在qdrant_storage目录,备份最简单的方式就是停掉Qdrant容器后打包目录:
bash复制docker compose stop qdrant
tar czf qdrant_backup.tar.gz qdrant_storage
docker compose start qdrant
WeKnora自己的配置和数据在data目录,同样打包。建议定期执行备份,尤其是新增了大量文档之后。恢复时把压缩包解压到原路径,重新启动容器即可。
7.2 版本升级与回滚
升级分三步:备份数据、拉取新镜像、替换容器。
bash复制docker compose pull weknora
docker compose up -d weknora
启动后发现异常,回滚也很简单:在compose文件里把镜像tag改回旧版本,再执行up。更新前先看官方文档的发布说明,注意版本间是否有数据库迁移或配置项变更。尤其是向量数据库版本,如果Qdrant跨了大版本,建议在测试环境先验证再上生产。
7.3 日常监控与日志
容器起来之后不要不管它。我习惯设置Docker日志上限,避免日志膨胀占满磁盘。在compose文件里给服务加日志滚动配置:
yaml复制logging:
driver: json-file
options:
max-size: "20m"
max-file: "3"
这一行很多人会忽略,但运行久了就会发现日志文件越来越大。配置好滚动之后,日志会按大小自动切割,省去手工清理的麻烦。日常再定时查看docker compose ps,有异常及时处理,系统就能保持长期稳定运行。
最后说点我自己的体会。用Docker部署WeKnora,最花时间的往往不是Docker本身,而是理解这条RAG链路里每个环节的意义。compose文件只是把组件拼起来,真正决定知识库问答质量的,是嵌入模型选型、切片参数、文档清洗这些细节。我的建议是,第一步先把服务跑起来,上传几份典型文档,用真实业务问题反复测;第二步再根据回答质量慢慢调参。很多人一上来就追求大规模、高性能,结果基础配置没弄对,效果一塌糊涂。先小规模跑通,再逐步优化,这个顺序比什么都重要。后续如果团队需要更强的Agent能力或者多模态文档支持,这套Docker化架构还可以继续扩展,但底座稳了,一切才有的聊。
