
最近在帮团队内部部署一套私有化知识库问答系统调研了好几轮之后最后选了 openJiuwen。理由其实挺简单它开源、组件不复杂、支持本地大模型而且自带一套可定制的一键安装脚本。我这次负责的是 Windows 环境适配因为团队里好几台办公机都是 Windows主力机型没有 Linux 服务器所以整个部署过程都是在 Windows 环境下完成的。说实话openJiuwen 的官方文档默认假设你用的是 Linux直接照着仓库里的install.sh在 Windows 上跑基本上第一步就会卡住。踩完一圈坑之后我把整个流程重新梳理了一遍从 WSL2 准备、Docker Desktop 配置、环境变量修改到一键脚本执行、知识库初始化和问答验证整理成一份可以直接照做的 Windows 部署指南。这篇内容面向的是想在自己 Windows 电脑上快速跑起来 openJiuwen 的人不管你是做知识库管理、文档问答还是想体验一下 RAG 应用的完整落地过程跟着做就行。1. openJiuwen 是什么为什么 Windows 环境要单独写一篇在动手之前我建议先把 openJiuwen 的整体结构搞清楚。它不是一个大而全的怪物项目而是一个典型的知识库问答系统核心逻辑可以概括成两件事文档处理链路和问答链路。文档处理上传 PDF、Word、Markdown 等文件系统会做文本切分、向量化然后存入向量数据库。问答链路用户提问时系统先从向量库检索相关段落拼接到 Prompt 里再交给大模型生成回答。这种架构在 RAG 应用里已经非常成熟好处是你不需要微调模型只需要管理好文档和检索质量就能获得还不错的回答效果。1.1 核心架构先看懂openJiuwen 的前端是 Vue 3后端是 FastAPI向量数据库用的是 Qdrant模型推理部分支持 Ollama 本地模型也支持 OpenAI 兼容接口。部署形态默认是 Docker Compose 编排的几个容器所以只要 Docker 环境没问题理论上在什么地方都能跑。我在项目根目录看到的典型结构大概是这样组件作用说明web前端界面负责登录、知识库管理、问答交互backend后端 API 服务提供文档解析、切片、检索、对话接口qdrant向量数据库存储文档向量和元数据负责相似度检索worker异步任务处理处理文档导入、索引构建等耗时任务刚开始我不太理解为什么要单独拆一个 worker后来实际导入一批几百页的 PDF 才意识到如果不把文档解析和向量构建放到后台任务里前端界面会直接卡死。这个设计在 Windows 部署时没有太大影响但你会更容易观察到容器重启的现象原因往往是任务处理时内存被吃满。1.2 为什么 Windows 上坑很多我之所以强调“Windows 环境适配”不是因为项目本身有问题而是因为 Windows 和 Linux 在部署习惯上差异太大。项目自带的一键安装脚本是用 Shell 写的Windows 下不能直接执行。Docker Desktop 在 Windows 上默认依赖 WSL2很多人第一次装完 Docker Desktop 之后发现镜像拉不下来容器起不来就是因为 WSL2 没有正确启用。还有一类问题是 Windows 特有的路径和权限问题。比如 Docker 挂载目录时如果路径包含中文或者空格容器的挂载可能失败。再比如 PowerShell 默认执行策略会拦截脚本右键运行.ps1文件时经常弹一下就没了。这些问题不解决你会觉得 openJiuwen 本身有问题实际上环境和脚本调用方式占了一大半。1.3 一键脚本是怎么设计出来的官方仓库里的install.sh虽然不适合 Windows但它的阶段划分很合理我做 Windows 版脚本时直接沿用了这个思路环境预检、配置准备、启动服务、等待就绪。四个阶段可以避免很多问题。环境预检检查 Docker 是否安装、Docker Desktop 是否在运行。配置准备如果.env文件不存在自动从.env.example复制一份。启动服务执行docker compose up -d拉取镜像并启动容器。等待就绪等待几秒后查看容器状态。这个设计的好处是出问题时能快速定位脚本不会稀里糊涂地跑一半然后退出。后面我会把完整的脚本贴出来并且逐段说明它在 Windows 下是如何工作的。2. Windows 环境准备部署前必做很多人一上来就急着跑安装脚本结果卡在 Docker 环境上。Windows 下部署 openJiuwen前置条件比 Linux 多一步而且每一步都有关联。我按顺序讲清楚。2.1 先确认虚拟化已经开启WSL2 和 Docker Desktop 都需要 CPU 虚拟化支持。你可以打开任务管理器切到“性能”标签页查看“虚拟化”那一项。如果显示“已启用”跳过这一步如果显示“已禁用”需要进 BIOS 开启 Intel VT-x 或者 AMD-V不同品牌主板的入口不同一般是开机时按 Del 或者 F2。确认虚拟化没问题之后在 PowerShell 里执行wsl --install -d Ubuntu-22.04这条命令会启用 Windows 的 WSL 功能并安装 Ubuntu 发行版。安装完需要重启一次。重启后继续执行wsl --set-default-version 2 wsl --status看到默认版本是 2就说明 WSL2 已经可用了。如果你之前装过旧版 WSL可能需要手动更新一次内核Windows 会给出提示按提示下载更新包就行。注意如果使用的是 Windows 10 较旧的版本wsl --install可能不存在需要先手动启用“适用于 Linux 的 Windows 子系统”和“虚拟机平台”两个可选功能再重启。2.2 安装 Docker Desktop注意选对后端安装 Docker Desktop 时安装向导会让你选择使用 Windows 容器还是 Linux 容器openJiuwen 的镜像都是 Linux 容器所以必须选 Linux containers。安装完成后在 Docker Desktop 的设置里确保“General”页勾选了 “Use the WSL 2 based engine”。只有勾选这一项容器才能真正跑在 WSL2 里而不是 Hyper-V两者资源消耗差异很大。打开 WSL Integration把刚才安装的 Ubuntu 发行版启用集成。这一步是为了后续在 WSL 终端里也能调用 docker 命令虽然我们主要用 PowerShell但有些排查操作用 WSL 更顺手。如果你的系统盘空间紧张建议在 Docker Desktop 里把镜像存储目录改到其他盘。设置项在 “Resources” - “Advanced”修改 Disk image location。之前我在 C 盘装了一堆镜像没几天存储空间就告急了改到 D 盘之后清净很多。2.3 配置 .wslconfig 限制资源WSL2 有一个常见问题默认会动态占用大量内存Windows 上运行 Docker Desktop 时经常感觉系统很卡。解决办法是手动创建一个.wslconfig文件放在你的用户目录下路径一般是C:\Users\你的用户名\.wslconfig。内容可以参考下面的写法[wsl2] memory8GB processors4 swap2GB如果你是 16GB 内存的机器建议memory8GB如果是 32GB 内存可以给到 12GB 或 16GB。修改完成后在 PowerShell 里执行wsl --shutdown再重新启动 Docker Desktop配置才会生效。我一开始没设这个限制跑了几个容器后内存占用到了 90%系统几乎无法操作。2.4 端口规划与占用检查openJiuwen 默认会用几个端口我列一个表格方便对照服务默认端口作用前端 Web8080浏览器访问页面后端 API8000REST API 服务Qdrant6333向量数据库 HTTP 接口Ollama可选11434本地模型推理接口部署前可以先检查端口是否被占用使用 Windows 自带命令netstat -ano | findstr :8080如果端口被占用输出里会显示占用进程的 PID然后用tasklist | findstr PID查看是哪个程序。端口被占的时候不需要强行杀进程可以直接在.env里修改APP_PORT。2.5 准备模型文件或 API 密钥openJiuwen 本身不包含大模型你需要提前准备好一个可用的推理后端。最方便的方案是本地 Ollama安装后在命令行执行ollama pull qwen2.5:7b模型文件比较大注意存放磁盘剩余空间。如果希望模型不占用系统盘可以设置环境变量OLLAMA_MODELS指向其他目录再重启 Ollama。如果团队已经有 OpenAI 兼容接口也可以直接配置接口地址和密钥不用在本地下载模型。3. 一键安装部署实操过程环境准备好之后这才进入正题。我会按实际操作的顺序来写每一步对应什么命令、执行的目是什么都单独说明。3.1 获取安装文件建议先把项目代码下载到固定目录比如D:\apps\openjiuwen。用 Git 拉取的话Windows 上经常遇到长路径问题Git 默认会拒绝超过 260 字符的文件路径。提前执行下面这条命令可以避免git config --global core.longpaths true然后拉取仓库git clone https://github.com/openjiuwen/openjiuwen.git不想用 Git 的话也可以直接在 GitHub 页面下载 zip 压缩包解压到目标目录。两种方式效果一样只是后续升级方式不同用 Git 拉取的话以后git pull就能升级。项目文件里你会看到docker-compose.yml、.env.example、install.ps1这些文件。我在 Windows 适配时新增了install.ps1和install.bat方便不同习惯的人使用。3.2 修改 .env 配置复制一份环境变量文件Copy-Item .env.example .env然后用记事本或者 VS Code 打开.env文件。几个关键变量必须核对APP_PORT8080 BACKEND_PORT8000 QDRANT_PORT6333 LLM_PROVIDERollama LLM_MODELqwen2.5:7b OLLAMA_BASE_URLhttp://host.docker.internal:11434 DEFAULT_EMBEDDING_MODELbge-m3这里有个特别容易踩的坑如果 openJiuwen 后端运行在 Docker 容器里而 Ollama 跑在宿主机上后端容器访问宿主机时不能写127.0.0.1因为容器里的127.0.0.1指向容器自身。Docker Desktop 提供一个特殊域名host.docker.internal会自动解析到宿主机地址。Linux 上才需要--add-host手动处理Windows 上一般不用操心。如果你的机器没有独立显卡只靠 CPU 跑 7B 模型会比较慢但并不是不能跑。回答一句话大概要等十几秒做技术验证完全够用。3.3 执行 PowerShell 一键安装脚本在项目根目录打开 PowerShell执行.\install.ps1脚本内容建议自己先看一眼因为它会把安装过程透明地展示给你。我用的是这个版本# openjiuwen-install.ps1 $ErrorActionPreference Stop Write-Host [1/4] 检查 Docker 环境... docker info * $null if ($LASTEXITCODE -ne 0) { Write-Host Docker 未启动请先打开 Docker Desktop。 -ForegroundColor Red exit 1 } Write-Host [2/4] 准备环境变量... if (-not (Test-Path .env)) { Copy-Item .env.example .env } Write-Host [3/4] 启动容器... docker compose up -d Write-Host [4/4] 等待服务就绪... Start-Sleep -Seconds 10 docker compose psdocker info只是探测 Docker 是否可用不产生实际输出。这里我用* $null把输出重定向掉避免一堆英文日志干扰视线。如果 Docker Desktop 没有启动脚本会在第一步退出并给出明确提示。在 Windows 上运行 PowerShell 脚本时可能会提示“无法加载文件因为在此系统上禁止运行脚本”。这是执行策略在拦截不代表脚本有病毒。临时放行当前进程即可Set-ExecutionPolicy -Scope Process Bypass再重新执行.\install.ps1。还有一种方式是一行命令直接绕过策略powershell -ExecutionPolicy Bypass -File install.ps1如果习惯用 CMD我也准备了一个install.batecho off echo [1/4] 检查 Docker 环境... docker info nul 21 if errorlevel 1 ( echo Docker 未启动请先打开 Docker Desktop。 exit /b 1 ) echo [2/4] 准备环境变量... if not exist .env ( copy .env.example .env ) echo [3/4] 启动容器... docker compose up -d echo [4/4] 等待服务就绪... timeout /t 10 /nobreak nul docker compose ps3.4 启动后确认服务状态脚本执行完进入最后一步检查状态。当你执行docker compose ps时应该看到所有服务状态都是running。如果某个容器状态是Restarting或者Exited马上查看日志docker compose logs --tail100 backend首次启动时后端可能会创建数据库表初始化速度取决于 CPU 性能通常等 10 到 20 秒就能访问。浏览器打开http://localhost:8080看到登录页面就说明基本跑起来了。4. 初始化系统导入文档并验证问答服务能访问只是第一步整个流程走得通才算成功。初始化 openJiuwen 分为账号创建、知识库建立、文档导入、绑定模型、问答验证五个环节。4.1 创建管理员账号第一次打开页面系统会引导你创建管理员账号。这里的账号是整个系统的主账号建议用企业邮箱或固定用户名因为后续添加成员、分配权限都要围绕这个管理员身份操作。创建完成后进入系统后台先不要急于上传文档花两分钟把系统设置里默认参数过一遍。openJiuwen 里所有知识库都是挂在组织空间下的管理员账号默认拥有全部权限。如果你是单机使用不需要额外建组织直接创建一个知识库就能开始。4.2 新建知识库并设置文档切分参数点击“知识库”菜单新建一个测试知识库名称可以取“运营手册测试库”。知识库创建后会要求设置文档处理参数核心参数是两个参数默认值说明切分长度512每段文本包含的字符数重叠长度50两段之间的重叠字符数切分长度太短语义会被打散太长则检索精度下降而且消耗的 token 会明显增加。我实际测试下来技术类文档用 512 比较平衡。重叠部分的作用是保留上下文之间的过渡信息避免关键句子被从中间截断。选嵌入模型时默认的bge-m3对中文支持很好如果你的 Ollama 没拉取这个模型启动时 worker 可能会报错需要先执行ollama pull bge-m3。我这里建议主聊天模型和嵌入模型分开配置不要用同一个模型否则显存和内存压力都会更大。4.3 导入文档并观察索引构建在知识库里上传 PDF 或 Markdown 文件系统会提示文件已经进入任务队列。打开日志确认进度docker compose logs -f worker正常情况下你会看到文档解析、切分、向量化、写入 Qdrant 的过程。这一步最容易出问题的是内存不足尤其是同时打开多个大 PDF 时Python 解析进程会被操作系统杀掉。我的建议是一次只导入一两份大文档批量操作放到晚上进行。4.4 绑定推理模型进入模型设置页面配置聊天模型的服务地址。因为 Ollama 运行在宿主机openJiuwen 容器里需要通过http://host.docker.internal:11434访问。配置完成后点击测试连接系统会返回模型列表让你确认。如果测试失败八成是模型名填错了先运行ollama list看准确的模型标识。4.5 完整问答验证到这里就可以问一个跟文档内容相关的问题。比如你上传了一份《FAQ 手册》可以问“退货流程中需要注意哪些事项”。如果回答质量满意说明整条链路是通的。如果回答明显偏离文档内容或者出现“根据提供的信息无法回答”的情况下一步去查看日志确认检索到了哪些段落。日志里会打印命中的文本片段你可以据此调整切分长度或者文档结构。4.6 Windows 防火墙与局域网访问如果只有本机访问默认配置就够了。如果是团队内部要共享需要开放防火墙的入站端口。在“Windows 安全中心”的“高级安全”里添加入站规则放行 TCP 8080或者直接在 PowerShell 以管理员身份执行New-NetFirewallRule -DisplayName openJiuwen Web -Direction Inbound -Protocol TCP -LocalPort 8080 -Action Allow局域网其他电脑访问时输入http://你的IP:8080即可。注意如果你改了端口把 8080 换成实际端口。5. 常见问题速查与避坑实录这部分是我在多次部署中最想分享的内容几乎每一个问题都遇到过一次。按现象排查会省很多时间。5.1 脚本闪退或提示禁止运行脚本PowerShell 脚本双击或右键运行时闪退通常有三种原因。当前 PowerShell 执行策略限制这种最常见。当前工作目录不对脚本里用Test-Path .env探测相对路径如果不在项目根目录自然会失败。杀毒软件把docker.exe或docker compose调用拦截了这个安全软件日志里会看到记录。我的建议是不要直接双击运行脚本而是先打开 PowerShell手动切换到项目目录再执行.\install.ps1。这样即使报错窗口也来得及显示。如果已经在项目根目录执行策略仍然是限制状态就按前面说的用Bypass参数执行。5.2 容器启动后一直重启容器一直重启最常见的是 Qdrant 或后端访问模型失败。看日志docker compose logs --tail50 qdrantQdrant 不断重启通常和数据目录权限有关Windows 挂载目录的权限模型和 Linux 不一样如果挂载路径带中文或空格更容易触发。我在实际部署时发现直接使用 Docker 命名的卷不要手动映射到 Windows 目录稳定性会好很多。比如docker-compose.yml里把./qdrant_storage:/qdrant/storage改成qdrant_data:/qdrant/storage。后端不断重启则十有八九是和模型通信超时检查 Ollama 是否运行以及host.docker.internal是否能被容器解析。进入容器来验证最直观docker compose exec backend curl http://host.docker.internal:114345.3 端口打不开或容器状态正常但页面 502状态正常但页面打不开可以先看前端容器日志。如果是 502通常是向后端请求时后端的地址配置不对。docker-compose.yml里的服务名在容器网络中可以直接作为主机名访问不要把后端地址写成localhost。正确写法是让前端容器通过http://backend:8000访问后端。5.4 索引构建完成但查询结果为空这个坑藏得很深。表面上看文档上传成功向量化也完成了但实际检索不到内容。查日志后发现问题出在嵌入模型和检索模型不匹配。比如文档向量化用bge-m3问答时配置里又指定了其他嵌入模型或者模型名写错导致查询向量和库里的向量不在一个语义空间。排错顺序是先确认 Ollama 列表里的嵌入模型存在再确认.env里DEFAULT_EMBEDDING_MODEL和知识库配置一致。5.5 数据备份与恢复openJiuwen 的数据主要存在两个地方数据库和 Qdrant 向量库。如果 Docker 卷挂载正常备份用一条 tar 命令就能完成docker run --rm -v openjiuwen_qdrant:/data -v D:\backup:/backup alpine tar czf /backup/qdrant-backup.tar.gz -C /data .恢复时把压缩包解压回卷内docker run --rm -v openjiuwen_qdrant:/data -v D:\backup:/backup alpine tar xzf /backup/qdrant-backup.tar.gz -C /data另外别忘了备份.env文件环境变量是整套部署的配置核心。我建议把.env文件也复制一份到备份目录不然恢复完容器配置对不上等于白恢复。6. 部署完成之后还可以做什么环境跑通以后别急着把所有文档一窝蜂传上去。先让一两个人真实使用一段时间看看检索质量是否满意。我这里分享几个从实际使用中总结的优化方向。6.1 调整并发与资源如果多人同时使用后端 API 默认的并发可能不够。你可以在.env里调整 worker 数量和超时时间。不过我先提醒一点Windows 上做并发压测时WSL2 的性能会明显低于裸 Linux这是因为磁盘 IO 经过了一层虚拟化。最好不要拿它当生产服务器来打高并发二三十人的内部使用完全没问题。6.2 设置开机自启动Windows 办公机重启后Docker Desktop 不会自动运行openJiuwen 的服务自然也不会启动。解决方式是制作一个自启动脚本。在项目根目录建一个start.batecho off cd /d D:\apps\openjiuwen docker compose up -d把这个start.bat的快捷方式放到 Windows 的“启动”文件夹里。Docker Desktop 本身可以在设置里设置开机启动两者配合重启后就能自动恢复服务。6.3 升级前先备份openJiuwen 迭代很快升级前不要直接覆盖目录。先备份数据再执行git pull docker compose pull docker compose up -d如果跨了大版本数据库结构可能变化建议在测试环境先验证再应用到正式环境。我曾经直接在生产环境升级过一次结果旧的向量数据还能用但数据库结构不兼容花了不少时间回滚。6.4 日志保留与磁盘清理Docker 容器运行久了日志文件会占用不少磁盘空间。尤其 openJiuwen 里 worker 打的日志非常多。Windows 上清理日志可以直接docker system prune -f --volumes这条命令慎用它会清理所有未使用的卷如果没有备份数据会非常危险。更安全的做法是在docker-compose.yml里加上日志轮转配置限制单个日志文件大小和保留数量从根源上解决问题。最后再分享一个小技巧部署过程中如果觉得中文文档切片后检索效果不好可以在文档段落之间插入清晰的标题让系统切分出来的段落边界更自然。切分算法再智能也抵不过源文档结构混乱带来的噪音。openJiuwen 本身的部署难度不算高只要 Windows 环境处理到位整个流程跑通之后后面维护起来会非常顺。