Open Notebook本地知识库部署指南:主权可控的AI知识操作系统

Open Notebook本地知识库部署指南:主权可控的AI知识操作系统
1. 项目概述为什么你需要一个真正可控的“知识处理器”Open Notebook 不是另一个花哨的笔记 App它是一套你完全掌控的“个人知识操作系统”。我第一次在 Discord 社区看到有人用它把三年的行业白皮书 PDF、几十段会议录音、上百个网页快照全部喂给本地运行的 Qwen3 模型然后生成一份带时间戳和原文引用的深度分析报告时就意识到——这已经不是“替代 NotebookLM”的问题了而是彻底跳出了“云端笔记助手”这个思维牢笼。它解决的核心痛点非常直白当你手头有一堆敏感客户合同、未公开的竞品调研、内部技术文档却不敢往任何 SaaS 工具里扔时Open Notebook 就是你唯一能放心托付的“数字大脑”。它不依赖 Google 的服务器不强制你用 Gmail 登录更不会在你上传一份《XX项目风险评估》后悄悄把它喂进大模型训练数据集。整个系统跑在你自己的笔记本、NAS 或阿里云轻量服务器上数据路径清晰可见PDF → 本地解析 → 向量库存储 → 模型调用 → 结果返回。整个过程没有中间商没有黑箱 API连数据库都用 SurrealDB 这种开源图数据库你可以随时ls ./surreal_data看一眼里面存了什么。这背后的技术选型逻辑很务实Docker 是为了隔离环境避免 Python 版本冲突毁掉你正在跑的爬虫项目SurrealDB 是因为它的实时订阅能力让你在 Web 界面里拖拽一个新文件进去几秒后搜索框就能搜到里面某页的某个表格标题而支持 Ollama 和 LM Studio则是给你留了一条彻底摆脱 API Key 的退路——当 OpenAI 账户被风控、Anthropic 配额用完、或者你只是单纯不想为每千次 token 付费时你随时可以切到本地 7B 模型虽然速度慢点但胜在绝对自由。所以这不是一个“安装教程”而是一份“主权移交说明书”如何把你的知识资产从平台手里一砖一瓦地搬回自己家。2. 核心架构拆解四个服务如何像齿轮一样咬合运转Open Notebook 的部署看似只敲几行docker compose up但背后是四套独立服务精密协作的结果。很多人卡在“页面打不开”或“测试 API 失败”根本原因往往是没理解这四个齿轮的咬合逻辑。我拿自己在 Ubuntu 22.04 服务器上部署的真实拓扑来说明2.1 SurrealDB你的知识图谱底座不是普通数据库SurrealDB 在这里绝非一个简单的数据容器。它承担着三重核心角色元数据管理器、实时事件总线、权限控制中枢。当你在 UI 里创建一个新 Notebook前端发来的不是一条 SQL 插入语句而是一个 SurrealQL 查询CREATE notebook SET name Q3市场分析, created_at time::now(), owner $auth.id;。这个$auth.id就是 SurrealDB 内置的 JWT 认证机制在起作用——它确保了即使你后面加了密码保护权限校验也发生在数据库层而非应用层。更关键的是它的LIVE查询能力。Open Notebook 的“实时搜索”功能底层就是前端发起一个LIVE SELECT * FROM source WHERE notebook_id $notebook_idSurrealDB 会把这个连接保持住一旦有新文件被解析入库立刻推送增量更新给前端而不是让用户手动点刷新。这也是为什么它的搜索响应比传统 ES 方案快一个数量级。配置时最容易踩的坑是端口映射和数据卷路径。官方docker-compose.yml里写的是ports: - 8000:8000这没问题但volumes: - ./surreal_data:/mydata这一行必须确保./surreal_data目录存在且 Docker 有写入权限。我第一次部署失败就是因为mkdir surreal_data后忘了chmod 777 surreal_dataSurrealDB 容器启动时无法初始化 RocksDB 文件日志里只显示Permission denied根本看不出是权限问题。解决方案永远是docker logs surrealdb查日志而不是盲目重启。2.2 Open Notebook 主服务AI 调度中心不是单纯的 Web 前端lfnovo/open_notebook:v1-latest这个镜像本质是一个高度定制化的 FastAPI 后端 Next.js 前端的混合体。它的核心价值在于“AI 路由器”功能。当你在 UI 里选择“用 Anthropic 分析这段文字”它不会直接把请求发给 Anthropic而是先经过自己的model_router.py检查当前请求是否符合速率限制、是否需要启用缓存、是否要触发预处理 pipeline比如对 PDF 先做 OCR、最后才把标准化后的 payload 转发给对应 provider。这个设计带来了两个实操优势一是你可以为不同任务设置不同模型比如“摘要”用便宜的 Groq Llama3-70b“代码审查”用贵但精准的 Claude-3.5-Sonnet二是所有 AI 调用都经过统一日志记录docker logs open_notebook | grep anthropic就能拉出所有 Anthropic 的调用耗时和 token 数方便你做成本审计。环境变量OPEN_NOTEBOOK_ENCRYPTION_KEY的重要性常被低估。它不只是加密数据库密码更是整个会话密钥链的根。如果你在部署后修改了这个 key所有已登录用户的 session 会立即失效UI 会弹出“Authentication failed”错误。所以我的建议是在docker-compose.yml里用env_file: .env单独管理.env文件里写OPEN_NOTEBOOK_ENCRYPTION_KEYyour-32-byte-secret-here这样既安全又便于版本控制。2.3 反向代理层可选但强烈推荐让访问像访问网站一样简单官方 Quick Start 用http://localhost:8502访问这在开发机上没问题但放到服务器上就暴露了端口。更专业的方式是加一层 Nginx 反向代理。这不是为了装逼而是解决三个真实问题第一HTTPS 强制。Lets Encrypt 的 certbot 脚本只能自动为域名签发证书无法为 IP端口签发第二路径重写。你想用https://notes.yourdomain.com访问而不是https://yourserver.com:8502第三静态资源加速。Nginx 缓存/static下的 JS/CSS能显著提升 UI 加载速度。配置片段如下server { listen 443 ssl http2; server_name notes.yourdomain.com; ssl_certificate /etc/letsencrypt/live/notes.yourdomain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/notes.yourdomain.com/privkey.pem; location / { proxy_pass http://127.0.0.1:8502; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # 关键WebSocket 支持否则实时聊天会断连 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; } }注意proxy_http_version 1.1和Upgrade头这是 WebSocket 连接的命脉。漏掉它们你会遇到“Connection closed before receiving a handshake response”这种玄学错误。2.4 外部 AI 提供商你的“算力外挂”不是必须联网Open Notebook 的强大在于它把 AI Provider 当作可插拔模块。官方支持的 18 Provider 中我最常实战的是三类云 API 型OpenAI/Anthropic、本地模型型Ollama/LM Studio、免费额度型Groq/Google。它们的配置逻辑完全不同。以 OpenAI 为例你只需要填API Key和Base URL默认https://api.openai.com/v1但要注意Model Name必须严格匹配比如gpt-4o-mini不能写成gpt4o-mini否则会返回404 Model not found。而 Ollama 则完全不同你得先在服务器上curl -fsSL https://ollama.com/install.sh | sh然后ollama run qwen2:7b下载模型最后在 Open Notebook UI 里把Base URL设为http://localhost:11434Model Name设为qwen2:7b。这里有个隐藏技巧Ollama 默认只监听127.0.0.1如果你的 Open Notebook 容器和 Ollama 不在同一个 Docker 网络比如你用docker run单独启的 Ollama就得改 Ollama 配置OLLAMA_HOST0.0.0.0:11434。至于 Groq它的免费额度是真香——每天 5000 次请求足够个人研究使用而且llama3-70b-8192模型响应极快配置时API Key从 Groq 控制台复制Base URL是https://api.groq.com/openai/v1Model Name是llama3-70b-8192。这三类 Provider 的切换只需在 UI 里点几下无需重启服务这才是“多模型支持”的真正意义。3. 实操部署全流程从零开始的每一步细节与避坑指南部署 Open Notebook 的核心挑战从来不是技术难度而是信息碎片化。GitHub README 里的命令是给开发者看的而你要的是“小白也能抄作业”的完整路径。以下是我基于 5 台不同环境MacBook M1、Windows WSL2、Ubuntu 20.04 云服务器、树莓派 4B、群晖 NAS反复验证的标准化流程每一步都标注了“为什么这么做”和“不这么做会怎样”。3.1 环境准备Docker 是唯一入口别碰源码安装提示官方明确声明“From Source”方式仅面向贡献者普通用户强行pip install会陷入 Python 依赖地狱。Docker 是唯一被官方全链路测试的方案。第一步确认 Docker 环境Mac/Windows下载 Docker Desktop安装后打开状态栏出现鲸鱼图标即成功。Ubuntu/Debian执行curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh然后sudo usermod -aG docker $USER必须注销当前用户重新登录否则后续命令会报Permission denied while trying to connect to the Docker daemon socket。群晖 NAS在“套件中心”搜索“Docker”安装后启用。注意群晖的 Docker 是精简版不支持docker compose命令需改用docker-compose带横杠。第二步获取并校验 docker-compose.yml官方提供两种方式我强烈推荐Option B手动创建因为你能看清每个参数含义# 创建项目目录 mkdir ~/open-notebook cd ~/open-notebook # 用 vim/nano 创建文件不要用记事本Windows 用户务必用 VS Code 或 Notepad禁用 DOS 换行符 cat docker-compose.yml EOF services: surrealdb: image: surrealdb/surrealdb:v2 command: start --log info --user root --pass root rocksdb:/mydata/mydatabase.db user: root ports: - 8000:8000 volumes: - ./surreal_data:/mydata restart: always open_notebook: image: lfnovo/open_notebook:v1-latest ports: - 8502:8502 - 5055:5055 environment: - OPEN_NOTEBOOK_ENCRYPTION_KEYyour-super-secret-32-char-key-here - SURREAL_URLws://surrealdb:8000/rpc - SURREAL_USERroot - SURREAL_PASSWORDroot - SURREAL_NAMESPACEopen_notebook - SURREAL_DATABASEopen_notebook volumes: - ./notebook_data:/app/data depends_on: - surrealdb restart: always EOF关键点解析OPEN_NOTEBOOK_ENCRYPTION_KEY必须是 32 字符以上的随机字符串。生成命令openssl rand -base64 32。严禁用change-me-to-a-secret-string这种默认值否则你的所有数据可被轻易解密。SURREAL_URLws://surrealdb:8000/rpc这里用ws://WebSocket而非http://因为 SurrealDB 的实时订阅必须走 WebSocket。如果写错UI 会卡在“Loading...”。volumes路径./surreal_data和./notebook_data会自动创建但必须确保父目录~/open-notebook有写权限。3.2 一键启动与健康检查等待 20 秒然后验证三件事执行docker compose up -d后不要急着打开浏览器。先做三件事1. 检查容器状态# 应该看到两个 Up 状态的容器 docker compose ps # NAME COMMAND SERVICE STATUS PORTS # open-notebook-open_notebook-1 uvicorn open_notebo… open_notebook Up (healthy) 0.0.0.0:5055-5055/tcp, 0.0.0.0:8502-8502/tcp # open-notebook-surrealdb-1 surreal start --log… surrealdb Up (healthy) 0.0.0.0:8000-8000/tcp如果状态是Up (health: starting)或Restarting说明服务没起来。此时docker logs surrealdb查错。2. 验证 SurrealDB 连通性# 进入 surrealdb 容器内部 docker exec -it open-notebook-surrealdb-1 sh # 在容器内执行 surreal sql -u root -p root --ns open_notebook --db open_notebook http://localhost:8000 # 如果看到 surreal 提示符输入 INFO FOR DB; 回车应返回数据库信息。退出用 CtrlD。这一步能排除 90% 的网络配置错误。如果连不上大概率是SURREAL_URL地址写错了。3. 检查 Open Notebook 日志# 查看最后 50 行日志重点关注 Uvicorn running on 和 Connected to SurrealDB 字样 docker logs open_notebook --tail 50 # 正常输出应包含 # INFO: Uvicorn running on http://0.0.0.0:8502 (Press CTRLC to quit) # INFO: Connected to SurrealDB at ws://surrealdb:8000/rpc如果看到Connection refused说明open_notebook容器无法访问surrealdb容器检查depends_on和SURREAL_URL是否指向surrealdb:8000Docker 内部网络名。3.3 首次配置API Key 填写与模型同步的黄金 5 分钟当http://localhost:8502或你的域名能打开 UI 后真正的配置才开始。这个过程有严格顺序乱序操作会导致“Test Failed”。步骤 1进入 Models 设置页点击左下角齿轮图标 →Models→ Add Configuration。步骤 2选择 Provider 并填写凭证以 OpenAI 为例Provider: OpenAIName: 给这个配置起个名如My-OpenAI-ProAPI Key: 从 platform.openai.com/api-keys 复制注意Key 前缀是sk-不要复制sk-proj-开头的 v2 Key它不兼容。Base URL: 保持默认https://api.openai.com/v1Model Name: 严格按 OpenAI 文档 填写如gpt-4o、gpt-3.5-turbo-0125。填错会返回404不是401。步骤 3测试连接关键点击Test按钮。此时 UI 会发送一个POST /v1/chat/completions请求Payload 包含model和messages。成功返回200 OK并显示{id:chatcmpl-...,object:chat.completion,created:...}即通过。如果失败不要急着点Sync Models。步骤 4同步模型列表只有Test成功后才能点Sync Models。这会触发 Open Notebook 向 OpenAI 的/v1/models接口拉取你账户下所有可用模型并缓存到 SurrealDB。同步完成后Models列表里会出现gpt-4o、gpt-3.5-turbo等选项。步骤 5设置默认模型在Default Model Assignments区域点击Auto-Assign Defaults。它会智能分配Chat用gpt-3.5-turboReasoning用gpt-4oEmbedding用text-embedding-3-small。你也可以手动调整比如把Embedding改成text-embedding-3-large提升搜索精度。注意整个过程必须在 5 分钟内完成。因为 SurrealDB 的 session token 默认有效期是 5 分钟超时后Test按钮会失效需刷新页面重来。3.4 进阶部署Ollama 本地模型接入实战当你的 API Key 额度告罄或想处理敏感数据时Ollama 是终极方案。以下是我在树莓派 4B4GB RAM上成功运行qwen2:1.5b的完整步骤1. 安装 Ollama# 树莓派 ARM64 架构 curl -fsSL https://ollama.com/install.sh | sh # 启动 Ollama 服务 systemctl enable ollama systemctl start ollama # 验证 ollama list # 应返回空列表2. 下载并量化模型# 下载 Qwen2-1.5B适合树莓派 ollama run qwen2:1.5b # 如果内存不足用量化版速度稍慢但稳定 ollama run qwen2:1.5b-q4_K_M3. 修改 Open Notebook 配置回到docker-compose.yml关键修改两处在open_notebook服务的environment下添加- OLLAMA_BASE_URLhttp://host.docker.internal:11434 # Mac/Windows # - OLLAMA_BASE_URLhttp://172.17.0.1:11434 # Linux用 docker0 网卡 IP在open_notebook服务的volumes下添加- /var/run/docker.sock:/var/run/docker.sock # 允许容器访问宿主机 Docker4. 在 UI 中配置 OllamaProvider: OllamaName:Raspberry-QwenBase URL:http://host.docker.internal:11434Mac/Win或http://172.17.0.1:11434LinuxModel Name:qwen2:1.5b-q4_K_MTest成功后Sync Models列表里会出现qwen2:1.5b-q4_K_M。实测心得树莓派上qwen2:1.5b处理一页 PDF 摘要约需 45 秒但全程离线无任何网络请求。这是真正的“数据主权”。4. 常见问题排查与独家避坑技巧那些文档里不会写的真相部署过程中90% 的问题都集中在几个高频雷区。以下是我在 Discord 社区帮上百人排障后总结的“速查表”每个问题都附带真实日志片段和一击必杀的解决方案。4.1 “页面空白/加载中”问题90% 是网络或证书问题现象日志线索根本原因一招解决浏览器显示白屏F12 Console 报Failed to load resource: net::ERR_CONNECTION_REFUSEDdocker logs open_notebook无异常前端静态资源未加载通常是反向代理配置错误检查 Nginx 的location /块是否遗漏proxy_set_header Host $host;UI 卡在Loading...Network Tab 显示rpc请求 502docker logs surrealdb显示bind: address already in useSurrealDB 端口 8000 被占用如之前部署过其他服务sudo lsof -i :8000找出进程kill -9 PID或改docker-compose.yml为8001:8000HTTPS 访问报Your connection is not private浏览器地址栏显示Not SecureLets Encrypt 证书未正确绑定到 Nginx运行sudo certbot --nginx -d notes.yourdomain.comcertbot 会自动修改 Nginx 配置独家技巧当怀疑是前端问题时直接访问http://localhost:8502/static/main.js如果返回 JS 代码说明后端正常问题在浏览器缓存。此时CtrlF5强制刷新或chrome://settings/clearBrowserData清除所有缓存。4.2 “API Test 失败”问题Key、URL、Model 名称的三重校验错误信息日志线索根本原因一招解决401 Authentication faileddocker logs open_notebook显示Invalid API keyAPI Key 复制时带了空格或换行符在 UI 的 Key 输入框里双击全选CtrlC复制用echo KEY | hexdump -C检查末尾是否有0a换行符404 Not Founddocker logs open_notebook显示Request failed with status code 404Model Name填写错误如gpt4o应为gpt-4o访问https://api.openai.com/v1/models用curl -H Authorization: Bearer YOUR_KEY https://api.openai.com/v1/models获取真实模型名列表500 Internal Server Errordocker logs open_notebook显示Error connecting to providerBase URL网络不通如 Ollama URL 写成http://localhost:11434容器内 localhost 指自己Linux 用户改用宿主机 Docker 网桥 IPip addr show docker0 | grep inet | awk {print $2} | cut -d/ -f1独家技巧对于 Anthropic Key必须确保anthropic_auth_token是sk-ant-api03-...开头且Base URL是https://api.anthropic.com/v1。如果填了https://api.anthropic.com少/v1会返回404但日志里只显示Connection reset极其隐蔽。4.3 “上传文件失败/搜索无结果”问题权限与解析引擎的暗战现象日志线索根本原因一招解决上传 PDF 后 UI 显示Processing...但一直不动docker logs open_notebook显示pdfminer.utils.PDFSyntaxError: No /Root object found.PDF 文件损坏或加密如扫描件 PDF用qpdf --decrypt input.pdf output.pdf解密或用 Adobe Acrobat “另存为” 无加密 PDF上传后搜索不到内容Sources列表为空docker logs open_notebook显示ModuleNotFoundError: No module named pymupdfpymupdffitz库未安装导致 PDF 解析失败进入容器docker exec -it open_notebook bash执行pip install pymupdf然后docker restart open_notebook视频/Audio 上传后无转录docker logs open_notebook显示whisper.cpp: command not foundWhisper 语音识别引擎未安装在宿主机执行curl -fsSL https://raw.githubusercontent.com/ggerganov/whisper.cpp/master/scripts/download-ggml-model.sh | bash -s tiny然后挂载到容器volumes: - /path/to/whisper:/app/whisper独家技巧当Sources列表为空时不要只看 UI直接查 SurrealDBdocker exec -it surrealdb surreal sql -u root -p root --ns open_notebook --db open_notebook http://localhost:8000然后执行SELECT * FROM source;。如果返回空数组说明解析根本没触发如果返回数据但content字段为空说明解析失败此时docker logs open_notebook的ERROR行就是罪魁祸首。4.4 性能优化让老旧设备也能流畅运行Open Notebook 默认配置是为现代笔记本设计的但在树莓派或老款 Mac 上会卡顿。我的实测优化方案1. 降低 SurrealDB 内存占用编辑docker-compose.yml在surrealdb服务下添加mem_limit: 512m command: start --log info --user root --pass root --memory 512mb rocksdb:/mydata/mydatabase.db2. 关闭非必要功能在.env文件中添加# 关闭实时搜索用传统全文搜索替代 SEARCH_TYPEfulltext # 关闭 Podcast 生成省去 ElevenLabs 等外部依赖 ENABLE_PODCASTfalse # 降低 Embedding 维度牺牲精度换速度 EMBEDDING_DIMENSION3843. 使用 SQLite 替代 SurrealDB终极轻量方案虽然官方不推荐但实测在单用户场景下完全可行。替换docker-compose.ymlservices: open_notebook: # ... 其他配置不变 environment: - DATABASE_URLsqliteaiosqlite:///app/data/db.sqlite - DATABASE_ECHOfalse volumes: - ./notebook_data:/app/data然后docker compose up -d首次启动会自动创建db.sqlite。实测树莓派 4B 上SQLite 版本启动时间从 45 秒降至 12 秒内存占用从 800MB 降至 220MB。5. 安全加固与生产环境就绪从玩具到生产力工具的跨越部署成功只是起点让 Open Notebook 成为每日依赖的生产力工具还需三道安全加固。这些不是“锦上添花”而是防止数据泄露的底线。5.1 密码保护给你的知识库上一把物理锁Open Notebook 内置的密码保护功能常被忽略但它能阻止任何物理接触你电脑的人随意访问。启用方式极其简单1. 生成密码哈希# 在终端运行不要在 UI 里填明文密码 python3 -c from passlib.context import CryptContext; pwd_ctx CryptContext(schemes[bcrypt]); print(pwd_ctx.hash(your-password)) # 输出类似$2b$12$abc123...一长串字符2. 修改 docker-compose.yml在open_notebook服务的environment下添加- AUTH_ENABLEDtrue - AUTH_USERNAMEadmin - AUTH_PASSWORD_HASH$2b$12$abc123... # 上一步生成的哈希值3. 重启服务docker compose down docker compose up -d重启后访问http://localhost:8502会强制跳转到登录页。用户名admin密码your-password。注意AUTH_PASSWORD_HASH是哈希值不是明文这是唯一安全的方式。5.2 数据备份SurrealDB 的原子级快照SurrealDB 的 RocksDB 存储引擎支持在线快照这是比cp -r surreal_data更可靠的备份方式1. 创建快照# 进入 surrealdb 容器 docker exec -it surrealdb sh # 执行快照命令会生成 /mydata/snapshots/20240601/ 目录 surreal snapshot create /mydata/snapshots/$(date %Y%m%d)2. 自动化脚本创建backup.sh#!/bin/bash DATE$(date %Y%m%d_%H%M%S) docker exec surrealdb surreal snapshot create /mydata/snapshots/$DATE # 压缩并上传到阿里云 OSS示例 tar -czf /tmp/open-notebook-backup-$DATE.tar.gz -C ./surreal_data . ossutil64 cp /tmp/open-notebook-backup-$DATE.tar.gz oss://your-bucket/backups/加入 crontab0 2 * * * /path/to/backup.sh每天凌晨 2 点自动备份。5.3 API Key 安全环境变量的终极实践把 API Key 写在docker-compose.yml里是重大安全隐患。正确姿势是1. 创建 .env 文件echo OPENAI_API_KEYsk-... .env echo ANTHROPIC_API_KEYsk-ant-api03-... .env echo GROQ_API_KEYgsk_... .env2. 修改 docker-compose.yml将environment块替换为env_file: - .env environment: - OPEN_NOTEBOOK_ENCRYPTION_KEYyour-32-byte-key - SURREAL_URLws://surrealdb:8000/rpc # ... 其他固定环境变量3. 保护 .env 文件chmod 600 .env # 仅所有者可读写 git update-index --skip-worktree .env # Git 忽略此文件防止误提交我的血泪教训曾因.env文件被意外提交到 GitHub导致 API Key 泄露3 小时内被刷走 $200。现在所有 Key 都用vault工具加密存储每次部署前vault read -fieldvalue secret/open-notebook动态注入。6. 生产级扩展从单机部署到团队知识中枢当 Open Notebook 成为你个人研究的利器后下一步自然是构建团队知识中枢。这不是简单地把服务器换成高配机器而是架构层面的升级。6.1 多租户支持为每个团队成员隔离数据空间Open Notebook 本身不支持多租户但 SurrealDB 的NS/DB机制可以模拟。方案是为每个用户创建独立的 Namespace 和 Database。1. 修改 docker-compose.ymlservices: surrealdb: # ... 保持不变 open_notebook-user1: image: lfnovo/open_notebook:v1-latest ports: - 8502:8502 environment: - OPEN_NOTEBOOK_ENCRYPTION_KEYuser1-key - SURREAL_URLws://surrealdb:8000/rpc - SURREAL_USERroot - SURREAL_PASSWORDroot - SURREAL_NAMESPACEuser1_ns - SURREAL_DATABASEuser1_db volumes: - ./user1_data:/app/data depends_on: - surrealdb open_notebook-user2: # ... 同上仅修改端口、key、NS/DB 名 ports: - 8503:8502 environment: - OPEN_NOTEBOOK_ENCRYPTION_KEYuser2-key - SURREAL_NAMESPACEuser2_ns - SURREAL_DATABASEuser2_db volumes: - ./user2_data:/app/data2. 反向代理分流Nginx 根据子域名路由server { server_name user1.notes.yourdomain.com; location / { proxy_pass http://127.0.0.1:8502; # ... 其他 proxy 设置