首页
/ Open Notebook 本地私有化部署实战:Docker Compose + Ollama 构建 100% 离线的 NotebookLM 式研究助手

Open Notebook 本地私有化部署实战:Docker Compose + Ollama 构建 100% 离线的 NotebookLM 式研究助手

2026-09-05 23:57:03作者:江焘钦

本文基于 Open Notebook 仓库的本地快速入门文档(quick-start-local.md)展开,讲解如何用 Docker Compose 把 Open Notebook、SurrealDB 和 Ollama 三个服务全部跑在同一台机器上,实现无需任何云 API Key、数据不出本机的 100% 本地 AI 环境。读完本文,你将掌握完整的本地部署流程:从编写 compose 文件、拉起服务、拉取模型,到在 UI 中配置 Ollama 凭据、注册模型、创建笔记本并对话,同时理解每个环境变量(如 OLLAMA_API_BASEOPEN_NOTEBOOK_ENCRYPTION_KEY)在源码中的实际作用与常见故障排查手段。

一、方案定位与适用场景

Open Notebook 的本地模式面向"隐私优先、零 API 费用"的使用场景:所有语言模型、向量嵌入都由 Ollama 在本地推理,适合离线环境、开发测试、以及不愿把研究资料上传到第三方云服务的用户。代价也很直接——响应速度取决于你的 CPU/GPU 性能,通常慢于云端模型。

仓库为此提供了完整的配套素材:

前置条件

  1. Docker Desktop(或 Docker Engine)已安装并可正常运行容器;
  2. 本地 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.pyPROVIDER_CONFIGollama 映射到 OLLAMA_API_BASE,运行时优先从数据库中的 Credential 记录读取,读不到时回退到环境变量;api/credentials_service.pycreate_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 凭据

  1. 进入 Manage → Models(当前版本 UI 中对应 Settings 区域);
  2. 点击 Add Credential
  3. 选择提供商:Ollama
  4. 命名,例如 "Local Ollama";
  5. Base URL 填写 http://ollama:11434(compose 内部地址,与第二节说明一致);
  6. 点击 Save
  7. 点击 Test Connection——应显示成功;
  8. 点击 Discover ModelsRegister Models,把已拉取的模型注册进 Open Notebook。

"Discover Models" 的底层就是第二节提到的 discover_ollama_models():它请求 Ollama 的 /api/tags,把返回的每个模型按名称分类为语言模型或嵌入模型。如果列表为空,通常意味着 Base URL 填错或模型还没拉完。

第二步:设置默认模型

  1. 仍停留在 Manage → Models
  2. 设置:
    • Language Modelollama/mistral(或你实际拉取的模型);
    • Embedding Modelollama/nomic-embed-text(未下载时会自动拉取);
  3. 点击 Save

语言模型负责对话与问答,嵌入模型负责把你的资料切成向量存入库中以供检索——这正是 Open Notebook "AI 上下文 / RAG" 工作方式的核心,可延伸阅读 AI Context / RAG 概念文档

五、创建第一个笔记本并完成首次对话

入门文档把"用起来"压缩为四步,正好覆盖了 NotebookLM 式工作流的最短闭环:

  1. 创建笔记本:点击 New Notebook,命名为 "My Private Research",点击 Create
  2. 添加本地内容:点击 Add Source → 选择 Text → 粘贴一段文本或文档内容 → Add。资料会被切块并生成嵌入向量(本地 Ollama 嵌入模型完成);
  3. 对话:进入 Chat,输入 "What did you learn from this?",发送;
  4. 观察本地 Ollama 模型基于你的资料生成回答。

验证清单

  • [ ] Docker 正在运行,三个容器均为 Up 状态
  • [ ] 可以访问 http://localhost:8502
  • [ ] Ollama 凭据已配置且 Test Connection 通过
  • [ ] 模型已注册(语言模型 + 嵌入模型)
  • [ ] 已创建笔记本
  • [ ] 本地模型可以正常对话

全部勾选通过后,你就拥有一个完全私有、可离线运行的研究助手了。

六、备选方案:用 LM Studio 替代 Ollama

如果你更习惯 GUI 管理模型,LM Studio 是面向非技术用户的替代选择。与 Ollama 容器的关键区别是:LM Studio 运行在 Docker 之外,Open Notebook 容器需要通过 host.docker.internal 才能访问它。

  1. 下载并安装 LM Studio(lmstudio.ai);
  2. 打开应用,从模型库下载一个模型;
  3. 进入 "Local Server" 标签页,启动本地服务器(默认端口 1234);
  4. 在 Open Notebook 中进入 Settings → API Keys
  5. 点击 Add Credential → 选择 OpenAI-Compatible
  6. Base URL 填写 http://host.docker.internal:1234/v1
  7. API Key 填写 lm-studio(占位值,LM Studio 不校验);
  8. 点击 Save,然后 Test Connection
  9. 在 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 ModelsRegister Models,新模型才会出现在可选列表中。

九、常见本地模型选择

入门文档给出的选型对照表(以 Ollama 模型名标注):

模型 速度 质量 VRAM 适用场景
mistral 良好 4GB 测试、日常使用
neural-chat 更好 6GB 均衡,推荐
llama2 最佳 8GB+ 复杂推理
phi 极快 一般 2GB 硬件吃紧时

仓库的 Ollama 配置指南(docs/5-CONFIGURATION/ollama.md)则列出了更新的模型建议,如 qwen3gemma3deepseek-r1phi4,嵌入模型推荐 mxbai-embed-large。可以推断实际选型时以你的硬件显存为准:先用小模型跑通全流程,再逐步升级到更大模型做"速度/质量"的本地基准测试。

十、部署之后的进阶方向

  • 切换模型:随时在 Settings → Models 中更换默认语言/嵌入模型;
  • 添加模型:Ollama 侧执行 ollama pull <model> 后重新 Discover;LM Studio 侧直接从应用模型库下载;
  • 部署到服务器:同一份 docker-compose.yml 适用于任何 Docker 环境(远程部署时务必守住"数据库端口只绑 127.0.0.1"这条安全底线,更多网络与代理细节见 docs/5-CONFIGURATION/security.mddocs/5-CONFIGURATION/reverse-proxy.md);
  • 云端混合:保留本地模型处理日常任务,同时添加云厂商凭据处理复杂任务,Open Notebook 的多凭据机制天然支持这种混合配置;
  • 丰富资料来源:添加 PDF、网页文章等更多类型的 Source,完整功能文档见 docs/3-USER-GUIDE/index.md,其中 添加资料指南有效对话指南 与本文的"创建笔记本 → 添加资料 → 对话"闭环直接衔接;
  • 本地语音能力:若希望播客/转录也完全本地化,可参考 完整本地栈示例(含 Speaches TTS/STT),对应配置文档为 docs/5-CONFIGURATION/local-tts.mddocs/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.pyopen_notebook/ai/model_discovery.py 中的具体读取位置,是排查"模型不可用"类问题的第一落脚点。按验证清单逐项打勾之后,你得到的就是一个数据不出本机、零 API 账单的 NotebookLM 式研究助手。

登录后查看全文
热门项目推荐
相关项目推荐