Open Notebook 本地私有化部署实战:Docker Compose + Ollama 构建 100% 离线的 NotebookLM 式研究助手
本文基于 Open Notebook 仓库的本地快速入门文档(quick-start-local.md)展开,讲解如何用 Docker Compose 把 Open Notebook、SurrealDB 和 Ollama 三个服务全部跑在同一台机器上,实现无需任何云 API Key、数据不出本机的 100% 本地 AI 环境。读完本文,你将掌握完整的本地部署流程:从编写 compose 文件、拉起服务、拉取模型,到在 UI 中配置 Ollama 凭据、注册模型、创建笔记本并对话,同时理解每个环境变量(如 OLLAMA_API_BASE、OPEN_NOTEBOOK_ENCRYPTION_KEY)在源码中的实际作用与常见故障排查手段。
一、方案定位与适用场景
Open Notebook 的本地模式面向"隐私优先、零 API 费用"的使用场景:所有语言模型、向量嵌入都由 Ollama 在本地推理,适合离线环境、开发测试、以及不愿把研究资料上传到第三方云服务的用户。代价也很直接——响应速度取决于你的 CPU/GPU 性能,通常慢于云端模型。
仓库为此提供了完整的配套素材:
- 本文所依据的入门文档:docs/0-START-HERE/quick-start-local.md;
- 仓库根目录的官方 compose 文件:docker-compose.yml(SurrealDB + Open Notebook 两服务版);
- 完整本地 AI 栈示例(额外包含 Ollama 与本地 TTS/STT 服务 Speaches):examples/docker-compose-full-local.yml;
- 深入的 Ollama 网络配置专题文档:docs/5-CONFIGURATION/ollama.md;
- 若你已经有本机安装的 Ollama(不打算用容器跑 Ollama),应改看 外部 Ollama 指南。
前置条件
- Docker Desktop(或 Docker Engine)已安装并可正常运行容器;
- 本地 LLM 运行时,二选一:
- Ollama(推荐,本文主线,将随 Compose 一起以容器方式运行);
- LM Studio(GUI 友好的替代方案,运行在 Docker 之外,见本文第六节)。
两种部署拓扑
入门文档把部署目标分为两类,本文的 compose 方案同时覆盖:
- 本地机器(同一台电脑):Open Notebook、SurrealDB、Ollama 全部跑在你当前这台机器上,适合测试和学习,是最简单的起步方式;
- 远程服务器(如 Raspberry Pi、NAS、云虚拟机):同一份
docker-compose.yml可以直接部署到另一台机器上,从你常用的电脑访问。注意远程场景下数据库端口绝不能对公网开放(原因见下节的端口绑定说明),网络配置细节可参考 Ollama 网络配置指南。
二、编写配置文件:三个服务的职责与关键参数
新建一个目录 open-notebook-local,在其中创建 docker-compose.yml。下面是入门文档给出的完整内容,可原样复制:
services:
surrealdb:
image: surrealdb/surrealdb:v2
command: start --user root --pass password rocksdb:/mydata/mydatabase.db
user: root
ports:
# Localhost only — the database uses default credentials, so never
# publish this port on 0.0.0.0
- "127.0.0.1:8000:8000"
volumes:
- ./surreal_data:/mydata
open_notebook:
image: lfnovo/open_notebook:v1-latest
pull_policy: always
ports:
- "8502:8502" # Web UI (React frontend)
- "5055:5055" # API (required!)
environment:
# Encryption key for credential storage (required)
- OPEN_NOTEBOOK_ENCRYPTION_KEY=change-me-to-a-secret-string
# Database (required)
- SURREAL_URL=ws://surrealdb:8000/rpc
- SURREAL_USER=root
- SURREAL_PASSWORD=password
- SURREAL_NAMESPACE=open_notebook
- SURREAL_DATABASE=open_notebook
# Ollama (required when running Ollama via Docker, as in this compose file)
- OLLAMA_API_BASE=http://ollama:11434
volumes:
- ./notebook_data:/app/data
depends_on:
- surrealdb
restart: always
ollama:
image: ollama/ollama:latest
ports:
- "11434:11434"
volumes:
- ./ollama_models:/root/.ollama
restart: always
# Optional: set GPU support if available
#deploy:
# resources:
# reservations:
# devices:
# - driver: nvidia
# count: 1
# capabilities: [gpu]
对照仓库源码,逐个说明关键配置项的含义:
1. SurrealDB 服务
command使用rocksdb:/mydata/mydatabase.db启动,即单文件 RocksDB 模式,数据落盘到挂载卷./surreal_data,容器重建后数据不丢失;- 端口映射刻意写成
127.0.0.1:8000:8000而非8000:8000。仓库的 docker-compose.yml 中对此有专门注释:由于数据库使用的是默认凭据,open_notebook服务通过 Compose 内部网络(ws://surrealdb:8000/rpc)访问数据库,宿主端口仅用于本地调试(例如用 Surrealist 或surreal sql客户端连接)。把它发布到0.0.0.0会让任何能访问该主机的客户端用默认凭据直接连入数据库,因此在远程部署时这一点尤其重要; - 仓库版本还支持
SURREAL_EXPERIMENTAL_GRAPHQL=true与通过.env变量SURREAL_USER/SURREAL_PASSWORD覆盖默认凭据(默认root:root),入门文档中的 compose 则直接把root/password写死在命令与open_notebook的环境变量里,两者一一对应即可。
2. open_notebook 服务
image: lfnovo/open_notebook:v1-latest是官方镜像;8502端口是 React 前端(Web UI),5055端口是 REST API,两者都需要发布;OPEN_NOTEBOOK_ENCRYPTION_KEY是必填项:它用于加密存入数据库的凭据(API Key、Base URL 等敏感字段)。仓库源码 open_notebook/utils/encryption.py 提供了加密实现,api/main.py 在启动流程中依赖该密钥。入门文档要求把它从change-me-to-a-secret-string替换为你自己的任意字符串——本地部署下"任意字符串"即可,但更换该密钥后已存储的凭据将无法解密,请勿事后随意更改;SURREAL_URL=ws://surrealdb:8000/rpc中的surrealdb是 Compose 服务名,即服务发现域名,与宿主端口127.0.0.1:8000无关;volumes中的./notebook_data:/app/data存放上传的源文件、生成的播客音频等用户数据。
3. Ollama 服务与 OLLAMA_API_BASE 的重要性
OLLAMA_API_BASE 是这份 compose 中最容易踩坑的变量,值得结合源码说明:
- 在 open_notebook/ai/provider_registry.py 中,Ollama 的
ProviderSpec声明了required_env=("OLLAMA_API_BASE",),即系统判定"Ollama 是否可用"的依据就是这一个环境变量; - 在 open_notebook/ai/model_discovery.py 中,
discover_ollama_models()读取OLLAMA_API_BASE(缺省回退到http://localhost:11434),然后请求{base_url}/api/tags接口枚举已拉取的模型,并按模型名自动分类为 language / embedding 类型; - 仓库 CHANGELOG.md 中记录过一个真实教训:早期的快速入门指南曾写成
OLLAMA_BASE_URL,而代码路径实际读取的是OLLAMA_API_BASE——照抄旧示例会导致 Ollama"静默不可用"且没有任何报错。三个随仓库发布的示例文件(包括本文引用的 compose)都已统一为正确名称,因此请确认你写的是OLLAMA_API_BASE; - 在容器化 Ollama 的场景下,Open Notebook 容器必须通过 Compose 网络内的服务名访问它,即
http://ollama:11434——这正是本文件open_notebook服务环境变量的取值。如果你改用宿主机上安装的 Ollama(容器外),则应改为http://host.docker.internal:11434(Linux 上还需extra_hosts配置,见 Ollama 配置指南 的"网络配置"章节)。
另外说明一点源码层面的机制:OLLAMA_API_BASE 属于"环境变量方式"配置 Ollama,而当前 UI 推荐的方式是在 Settings → API Keys 中创建 Ollama 凭据。二者并不冲突——open_notebook/ai/key_provider.py 中 PROVIDER_CONFIG 把 ollama 映射到 OLLAMA_API_BASE,运行时优先从数据库中的 Credential 记录读取,读不到时回退到环境变量;api/credentials_service.py 的 create_credential_from_env() 还会在检测到 OLLAMA_API_BASE 时自动生成一条"Default (Migrated from env)"凭据,完成从环境变量到 UI 凭据的迁移。所以本文 compose 中设置该变量、以及第六步在 UI 中添加凭据,两者是同一件事的容器侧与 UI 侧表达。
4. GPU 可选配置
compose 中被注释掉的 deploy.resources.reservations.devices 块用于 NVIDIA GPU 加速。如果你的机器有独显,取消注释后 Ollama 会使用 GPU 推理,响应速度显著提升;纯 CPU 环境下保持注释即可。
三、启动服务与拉取模型
1. 启动
在 open-notebook-local 目录下执行:
docker compose up -d
等待 10–15 秒,三个容器(SurrealDB、Open Notebook、Ollama)进入运行状态。可用 docker compose ps 确认。
2. 拉取模型
Ollama 至少要有一个语言模型。入门文档给出三个梯度(注意容器名 open-notebook-local-ollama-1 由目录名 open-notebook-local 派生,如果你的目录名不同,请先 docker ps 确认实际容器名):
# Fastest & smallest (recommended for testing)
docker exec open-notebook-local-ollama-1 ollama pull mistral
# OR: Better quality but slower
docker exec open-notebook-local-ollama-1 ollama pull neural-chat
# OR: Even better quality, more VRAM needed
docker exec open-notebook-local-ollama-1 ollama pull llama2
下载耗时约 1–5 分钟,取决于网络。向量嵌入模型(nomic-embed-text)在第七步配置 Embedding Model 时会按需自动下载;若想提前准备好,可以执行 docker exec open-notebook-local-ollama-1 ollama pull nomic-embed-text。仓库的完整本地示例 examples/docker-compose-full-local.yml 的注释中还列出了 mxbai-embed-large(约 334M 参数、质量更高)等可选嵌入模型。
3. 打开 Web UI
浏览器访问 http://localhost:8502,应看到 Open Notebook 界面。
四、在 UI 中配置 Ollama 凭据与模型
第一步:添加 Ollama 凭据
- 进入 Manage → Models(当前版本 UI 中对应 Settings 区域);
- 点击 Add Credential;
- 选择提供商:Ollama;
- 命名,例如 "Local Ollama";
- Base URL 填写
http://ollama:11434(compose 内部地址,与第二节说明一致); - 点击 Save;
- 点击 Test Connection——应显示成功;
- 点击 Discover Models → Register Models,把已拉取的模型注册进 Open Notebook。
"Discover Models" 的底层就是第二节提到的 discover_ollama_models():它请求 Ollama 的 /api/tags,把返回的每个模型按名称分类为语言模型或嵌入模型。如果列表为空,通常意味着 Base URL 填错或模型还没拉完。
第二步:设置默认模型
- 仍停留在 Manage → Models;
- 设置:
- Language Model:
ollama/mistral(或你实际拉取的模型); - Embedding Model:
ollama/nomic-embed-text(未下载时会自动拉取);
- Language Model:
- 点击 Save。
语言模型负责对话与问答,嵌入模型负责把你的资料切成向量存入库中以供检索——这正是 Open Notebook "AI 上下文 / RAG" 工作方式的核心,可延伸阅读 AI Context / RAG 概念文档。
五、创建第一个笔记本并完成首次对话
入门文档把"用起来"压缩为四步,正好覆盖了 NotebookLM 式工作流的最短闭环:
- 创建笔记本:点击 New Notebook,命名为 "My Private Research",点击 Create;
- 添加本地内容:点击 Add Source → 选择 Text → 粘贴一段文本或文档内容 → Add。资料会被切块并生成嵌入向量(本地 Ollama 嵌入模型完成);
- 对话:进入 Chat,输入 "What did you learn from this?",发送;
- 观察本地 Ollama 模型基于你的资料生成回答。
验证清单
- [ ] Docker 正在运行,三个容器均为 Up 状态
- [ ] 可以访问
http://localhost:8502 - [ ] Ollama 凭据已配置且 Test Connection 通过
- [ ] 模型已注册(语言模型 + 嵌入模型)
- [ ] 已创建笔记本
- [ ] 本地模型可以正常对话
全部勾选通过后,你就拥有一个完全私有、可离线运行的研究助手了。
六、备选方案:用 LM Studio 替代 Ollama
如果你更习惯 GUI 管理模型,LM Studio 是面向非技术用户的替代选择。与 Ollama 容器的关键区别是:LM Studio 运行在 Docker 之外,Open Notebook 容器需要通过 host.docker.internal 才能访问它。
- 下载并安装 LM Studio(lmstudio.ai);
- 打开应用,从模型库下载一个模型;
- 进入 "Local Server" 标签页,启动本地服务器(默认端口 1234);
- 在 Open Notebook 中进入 Settings → API Keys;
- 点击 Add Credential → 选择 OpenAI-Compatible;
- Base URL 填写
http://host.docker.internal:1234/v1; - API Key 填写
lm-studio(占位值,LM Studio 不校验); - 点击 Save,然后 Test Connection;
- 在 Settings → Models 中选择你的 LM Studio 模型。
七、本地部署的收益与代价
收益:
- 零 API 费用,长期使用无订阅;
- 无需互联网,具备真正的离线能力(模型下载完成后);
- 隐私优先——研究资料永不离开本机;
- 凭据加密存储(
OPEN_NOTEBOOK_ENCRYPTION_KEY),配置迁移成本低。
代价:响应速度受 CPU/GPU 限制,明显慢于云端模型;对复杂推理类任务,小参数本地模型的质量也有限。仓库的完整本地示例 examples/docker-compose-full-local.yml 给出了硬件参考:CPU 最低配置约 8 GB 内存、4 核、20 GB 磁盘;推荐配置 16+ GB 内存、8+ GB 显存(NVIDIA)、50 GB 磁盘、8+ 核。
八、故障排查(Troubleshooting)
以下问题与命令均继承自入门文档:
"ollama: command not found"
通常是因为容器名与假设的不一致。先查实际容器名再执行:
docker ps # Find the Ollama container name
docker exec <container_name> ollama pull mistral
模型下载卡住
检查网络后重启 Ollama 容器,再重试拉取:
docker compose restart ollama
"Address already in use"
宿主机端口被占用(常见于 8502/5055/11434/8000)。停掉旧栈后重建:
docker compose down
docker compose up -d
或者修改 compose 中的宿主端口映射(保持容器端口不变,如 "8503:8502")。
性能偏低
检查 GPU 是否可用:
# Show available GPUs / loaded models
docker exec open-notebook-local-ollama-1 ollama ps
然后按第二节说明在 compose 中启用 GPU 设备预留,并执行 docker compose restart ollama。
添加更多模型
# List available models
docker exec open-notebook-local-ollama-1 ollama list
# Pull additional model
docker exec open-notebook-local-ollama-1 ollama pull neural-chat
拉取新模型后,记得回到 UI 对该凭据重新执行 Discover Models → Register Models,新模型才会出现在可选列表中。
九、常见本地模型选择
入门文档给出的选型对照表(以 Ollama 模型名标注):
| 模型 | 速度 | 质量 | VRAM | 适用场景 |
|---|---|---|---|---|
| mistral | 快 | 良好 | 4GB | 测试、日常使用 |
| neural-chat | 中 | 更好 | 6GB | 均衡,推荐 |
| llama2 | 慢 | 最佳 | 8GB+ | 复杂推理 |
| phi | 极快 | 一般 | 2GB | 硬件吃紧时 |
仓库的 Ollama 配置指南(docs/5-CONFIGURATION/ollama.md)则列出了更新的模型建议,如 qwen3、gemma3、deepseek-r1、phi4,嵌入模型推荐 mxbai-embed-large。可以推断实际选型时以你的硬件显存为准:先用小模型跑通全流程,再逐步升级到更大模型做"速度/质量"的本地基准测试。
十、部署之后的进阶方向
- 切换模型:随时在 Settings → Models 中更换默认语言/嵌入模型;
- 添加模型:Ollama 侧执行
ollama pull <model>后重新 Discover;LM Studio 侧直接从应用模型库下载; - 部署到服务器:同一份
docker-compose.yml适用于任何 Docker 环境(远程部署时务必守住"数据库端口只绑 127.0.0.1"这条安全底线,更多网络与代理细节见 docs/5-CONFIGURATION/security.md 与 docs/5-CONFIGURATION/reverse-proxy.md); - 云端混合:保留本地模型处理日常任务,同时添加云厂商凭据处理复杂任务,Open Notebook 的多凭据机制天然支持这种混合配置;
- 丰富资料来源:添加 PDF、网页文章等更多类型的 Source,完整功能文档见 docs/3-USER-GUIDE/index.md,其中 添加资料指南 与 有效对话指南 与本文的"创建笔记本 → 添加资料 → 对话"闭环直接衔接;
- 本地语音能力:若希望播客/转录也完全本地化,可参考 完整本地栈示例(含 Speaches TTS/STT),对应配置文档为 docs/5-CONFIGURATION/local-tts.md 与 docs/5-CONFIGURATION/local-stt.md。
小结
本地模式的全部工作量可以概括为"一份 compose 文件 + 一次模型拉取 + 两分钟 UI 配置":compose 定义 SurrealDB(数据)、Open Notebook(应用,8502/5055 端口)、Ollama(模型,11434 端口)三者的网络与卷;OPEN_NOTEBOOK_ENCRYPTION_KEY 保障凭据加密,OLLAMA_API_BASE 决定容器如何找到本地模型服务——这两个变量在源码 open_notebook/ai/provider_registry.py 与 open_notebook/ai/model_discovery.py 中的具体读取位置,是排查"模型不可用"类问题的第一落脚点。按验证清单逐项打勾之后,你得到的就是一个数据不出本机、零 API 账单的 NotebookLM 式研究助手。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00