news 2026/9/10 21:20:37

Open Notebook 基于 EasyPanel 模板的一键部署:模板结构、服务编排与环境变量全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Open Notebook 基于 EasyPanel 模板的一键部署:模板结构、服务编排与环境变量全解析

Open Notebook 基于 EasyPanel 模板的一键部署:模板结构、服务编排与环境变量全解析

【免费下载链接】open-notebookAn Open Source implementation of Notebook LM with more flexibility and features项目地址: https://gitcode.com/GitHub_Trending/op/open-notebook

EasyPanel 是一个图形化的自托管应用面板,通过"模板 + 可填写表单"的方式即可完成多服务应用的部署。Open Notebook 在 examples/easypanel 目录中提供了一套官方 EasyPanel 模板,把「Open Notebook 应用 + SurrealDB 数据库」两个服务封装为一个可复用的部署单元。读完本文,你将掌握该模板meta.yamlindex.ts的文件格式、每个配置字段的含义,了解两个服务各自暴露的端口、环境变量与持久化卷,并能够在 EasyPanel 中完成从模板导入、密码设置到首次登录配置 AI Provider 的完整实操流程。

模板定位:一次点击拉起「应用 + 数据库」

这套模板位于仓库 examples/easypanel/ 目录,由meta.yamlindex.ts两个文件组成,遵循 EasyPanel 官方模板仓库(easypanel-io/templates)的目录与代码约定:

  • meta.yaml:描述模板元数据与用户输入(input schema),即 EasyPanel 创建模板时展示给用户的表单;
  • index.ts:实现generate(input)函数,把用户的表单输入展开为具体的 EasyPanel services 定义。

模板部署后会创建两个服务

服务角色网络可见性说明
Open Notebook应用(Next.js 前端 + Python 后端)对外暴露,入口端口8502通过域名直接访问,反向代理友好
SurrealDB v2数据库仅项目内部网络可见通过ws://...:8000/rpc供应用连接,数据持久化在卷中

仓库根目录的 examples/README.md 也明确说明:该 easypanel 模板可直接复制进官方 EasyPanel 模板仓库,并在 EasyPanel templates playground 中测试。

meta.yaml:模板元数据与输入表单定义

examples/easypanel/meta.yaml 完整描述了模板的名称、说明、安装指引、变更日志、标签与输入项。其中schema部分是 EasyPanel 渲染创建表单的依据,共定义了 5 个输入字段:

字段类型标题默认值是否必填用途
appServiceNamestringApp Service Nameopen-notebook应用服务的名称
appServiceImagestringApp Service Imagelfnovo/open_notebook:1.10.0Open Notebook 镜像及版本标签
databaseServiceNamestringDatabase Service Namesurrealdb数据库服务的名称
databaseServiceImagestringDatabase Service Imagesurrealdb/surrealdb:v2SurrealDB v2 官方镜像
appPasswordstringOpen Notebook Password""(空)应用登录密码,留空则自动生成

值得注意的细节:appServiceImage默认值被固定为lfnovo/open_notebook:1.10.0(模板首个版本发布于 2026-06-19)。与之对照,仓库根目录 docker-compose.yml 使用的是滚动标签lfnovo/open_notebook:v1-latest。因此在 EasyPanel 上通过该模板部署后,如需升级版本,应修改这个输入项的镜像标签。

meta.yaml中还包含面向模板市场的展示信息:description介绍 Open Notebook 是开源自托管的 notebook 与研究型工作区,支持收集资料、记笔记、搜索、与内容对话及生成播客;instructions给出部署后的引导文案;benefitsfeatures分别说明模板带来的部署价值与产品能力(源码收集、notebook 组织、带引用的 AI 问答、播客生成);changeLoglinkscontributorstags则服务于模板仓库的版本与分类管理。

index.ts:一次 generate 调用编排两个服务

examples/easypanel/index.ts 是整个模板的核心逻辑。它从~templates-utils引入OutputrandomPasswordrandomStringServices等辅助工具,在generate(input)内完成密钥生成与服务定义:

export function generate(input: Input): Output { const services: Services = []; const appPassword = input.appPassword || randomPassword(); // 用户未填 → 自动生成 const databasePassword = randomPassword(); // 数据库密码随机生成 const encryptionKey = randomString(64); // 加密密钥随机生成(64 字符) // ...push SurrealDB service、push Open Notebook service... return { services }; }

三个关键密钥的生成策略正好呼应meta.yamlbenefits声明的 "Secure defaults":

  • appPassword:优先取用户在表单中填写的密码;留空则调用randomPassword()生成一个随机密码,并写入应用服务环境变量OPEN_NOTEBOOK_PASSWORD(README 中对该行为有专门说明);
  • databasePassword:每次模板创建都随机生成;
  • encryptionKey:每次模板创建都生成 64 字符的随机串,作为OPEN_NOTEBOOK_ENCRYPTION_KEY

每次在 EasyPanel 中执行模板创建,都会重新走一遍generate(),也就意味着会生成一组全新的随机密钥与数据库密码,它们被持久化在应用服务(app service)的环境变量中。

服务一:私有部署的 SurrealDB v2

模板把 SurrealDB 设计为"项目内部私有"服务,不对外暴露任何域名或宿主端口,应用在项目网络中通过内部 DNS 访问。其服务定义要点如下:

{ type: "app", data: { serviceName: input.databaseServiceName, env: [`SURREAL_EXPERIMENTAL_GRAPHQL=true`].join("\n"), source: { type: "image", image: input.databaseServiceImage }, deploy: { command: [ "start", "--log info", "--user root", `--pass ${databasePassword}`, "--bind 0.0.0.0:8000", "rocksdb:/mydata/mydatabase.db", ].join(" "), }, mounts: [{ type: "volume", name: "surreal-data", mountPath: "/mydata" }], }, }

几点值得展开:

  • 启动命令使用rocksdb:/mydata/mydatabase.db,即让 SurrealDB 以RocksDB 存储引擎运行,数据文件落在容器内/mydata/mydatabase.db
  • surreal-data挂载到/mydata,保证数据库文件在容器重建后依然存在;
  • 端口8000仅对项目网络内部开放,日志级别为info,凭据为root+ 随机生成的密码;
  • SURREAL_EXPERIMENTAL_GRAPHQL=true开启 SurrealDB 的实验性 GraphQL 支持,这与仓库根目录 docker-compose.yml 中 surrealdb 服务保持一致的配置习惯。

由于该服务在模板中并未配置domains,它不会被 EasyPanel 暴露到公网,这正是"数据库私密"这一安全设计的体现。

服务二:Open Notebook 应用与它的全部环境变量

应用服务承载了 Open Notebook 的 Web UI(Next.js 前端)与内部 REST API(FastAPI),通过domains把 EasyPanel 自动分配的域名映射到容器端口8502。模板为该服务注入了一批环境变量,它们是理解整套模板如何工作的钥匙:

env: [ `API_URL=https://$(PRIMARY_DOMAIN)`, `INTERNAL_API_URL=http://localhost:5055`, `OPEN_NOTEBOOK_ENCRYPTION_KEY=${encryptionKey}`, `OPEN_NOTEBOOK_PASSWORD=${appPassword}`, `SURREAL_URL=ws://$(PROJECT_NAME)_${input.databaseServiceName}:8000/rpc`, `SURREAL_USER=root`, `SURREAL_PASSWORD=${databasePassword}`, `SURREAL_NAMESPACE=open_notebook`, `SURREAL_DATABASE=open_notebook`, ].join("\n"), // domains: [{ host: "$(EASYPANEL_DOMAIN)", port: 8502 }] // mounts: [{ type: "volume", name: "notebook-data", mountPath: "/app/data" }]

下面逐一说明每个变量的作用,以及它们在 Open Notebook 运行时中的落点:

数据库连接变量

环境变量作用
SURREAL_URLws://$(PROJECT_NAME)_<databaseServiceName>:8000/rpcSurrealDB 的 WebSocket RPC 地址,$(PROJECT_NAME)_surrealdb是 EasyPanel 项目内部网络的域名规则
SURREAL_USERroot数据库用户名,与 SurrealDB 服务启动参数一致
SURREAL_PASSWORD随机生成数据库密码,与 SurrealDB 服务启动参数中的--pass相同
SURREAL_NAMESPACEopen_notebookSurrealDB 命名空间
SURREAL_DATABASEopen_notebookSurrealDB 数据库名

namespace/database两级命名对应 SurrealDB 的数据组织模型,在仓库根目录 docker-compose.yml 的多容器编排中使用的是同一组值(open_notebook/open_notebook),而 examples/docker-compose-single.yml 这类单容器场景则需覆盖为ws://localhost:8000/rpc。EasyPanel 模板选择 WebSocket RPC(ws://而非http://)作为连接协议,与官方 compose 部署保持一致。

认证与加密变量

OPEN_NOTEBOOK_PASSWORD(应用登录密码):这是模板中与用户体验直接相关的一个变量。若在创建表单中填写了密码,EasyPanel 会把它写入应用服务环境变量;若留空,模板会生成随机密码并同样以OPEN_NOTEBOOK_PASSWORD存储(见 README 与meta.yamlinstructions)。运行时层面,该变量驱动内置的密码认证中间件:从源码 api/auth.py 看,其认证器通过get_secret_from_env("OPEN_NOTEBOOK_PASSWORD")读取密码,并支持OPEN_NOTEBOOK_PASSWORD_FILE的 Docker secrets 形式;仓库变更记录 CHANGELOG.md 同时说明——OPEN_NOTEBOOK_PASSWORD未设置时,认证被完全禁用(本地零配置部署场景),而一旦设置即启用登录保护,前端对应 LoginForm.tsx 登录页。因此 EasyPanel 部署务必设置该密码。

OPEN_NOTEBOOK_ENCRYPTION_KEY(加密密钥):用于在数据库中加密保存用户配置的各类 AI Provider API Key。字段级加密实现位于 open_notebook/utils/encryption.py:它接受任意字符串作为密钥,通过 SHA-256 派生并转换为 Fernet 密钥,再使用 Fernet(AES-128-CBC + HMAC-SHA256 认证加密)完成加解密。该文件明确要求生产部署必须显式设置此变量,否则存储 API Key 时会因ValueError失败。模板每次创建都通过randomString(64)生成强随机密钥,比人工设置的弱口令安全得多。

前端反向代理相关变量

API_URL=https://$(PRIMARY_DOMAIN):浏览器端发起请求时使用的 API 基址。$(PRIMARY_DOMAIN)与后续domains中使用的$(EASYPANEL_DOMAIN)指向同一个公网域名。

INTERNAL_API_URL=http://localhost:5055:Next.js 服务端把/api/*请求内部转发到 REST API(运行在localhost:5055)所用地址。

两个变量分工的源码依据非常清晰。前端运行时配置 frontend/src/lib/config.ts 会先请求服务端/config接口获取apiUrl;而/config路由的实现 frontend/src/app/config/route.ts 明确注释了"为什么需要两个变量":API_URL供浏览器直接访问、可以是https://your-domain.com这类公网地址,INTERNAL_API_URL则供 Next.js rewrites 在服务端做代理转发(默认http://localhost:5055)。再看 Next.js 配置 frontend/next.config.ts:rewrites()/api/:path*代理到INTERNAL_API_URL对应的后端,注释直接说明——"反向代理只需把流量导到 8502,Next.js 负责内部把请求路由到 5055 的 API"。这正是meta.yaml中 "Reverse-proxy friendly" benefit 所描述的设计:只有前端端口(8502)被暴露

数据持久化

应用服务的卷notebook-data被挂载到容器内/app/data。为什么是这个路径?因为 Open Notebook 的数据根目录DATA_FOLDER = "./data"定义在 open_notebook/config.py(容器工作目录下即/app/data),其中包含 LangGraph 检查点 SQLite(sqlite-db/checkpoints.sqlite)、上传文件目录uploads/、播客输出目录podcasts/以及 tiktoken 缓存目录。把整个/app/data持久化为卷,可以确保会话检查点、上传的源文件、生成的播客音频与分词缓存都在容器重建后保留。数据库数据则由独立的surreal-data卷承载,与应用数据卷相互隔离。

端到端部署实操流程

结合 README 的 Testing 章节与meta.yamlinstructions,一次完整的部署包含以下步骤:

第 1 步:把模板放进 EasyPanel 模板仓库

将 examples/easypanel 整个目录复制到本地克隆的easypanel-io/templates仓库中,目录名改为templates/open-notebook

cp -r examples/easypanel <path-to-easypanel-io/templates>/templates/open-notebook

第 2 步:启动 EasyPanel 模板开发环境

easypanel-io/templates仓库根目录运行模板 playground:

npm run dev

playground 会读取模板目录下的meta.yamlindex.ts,渲染出与正式创建时一致的表单,方便你在导入实例前验证输入项与生成的 services JSON 是否符合预期。

第 3 步:在 EasyPanel 实例中创建模板并部署

  • 打开 EasyPanel 面板,通过模板管理导入上述目录生成的模板 JSON;
  • 在创建表单中至少确认appServiceNameappServiceImagedatabaseServiceNamedatabaseServiceImage四个必填项(均有合理默认值,通常无需改动);
  • 在 "Open Notebook Password" 字段设置一个应用密码。若留空,EasyPanel 会生成随机密码并把OPEN_NOTEBOOK_PASSWORD写入应用服务环境变量(可在服务环境变量面板中查看);
  • 提交创建。模板会依次生成 SurrealDB 服务与 Open Notebook 服务、挂载两个持久化卷、注入全部环境变量。

第 4 步:首次登录并配置 AI Provider

部署完成后,打开 EasyPanel 为应用分配的域名(流量经 EasyPanel 入口转发到容器的 8502 端口),使用你设置的密码登录。随后进入Settings > API Keys页面,配置所需的 AI 提供方密钥(如 OpenAI、Anthropic 或 Ollama 等本地模型)。这也是meta.yamlinstructions明确引导的流程。

安全与运维要点

基于模板实现与仓库源码,可以总结出以下运维注意事项:

  1. 数据库与加密密钥仅在创建时生成一次databasePasswordencryptionKeygenerate()在模板创建时生成并固化在服务环境中。如果日后重新从模板创建新服务或重建项目,会得到一组全新密钥,不会自动沿用旧值
  2. OPEN_NOTEBOOK_ENCRYPTION_KEY必须保持稳定:API Key 在入库前经 Fernet 加密(见 open_notebook/utils/encryption.py)。一旦更换密钥,已存储的加密凭据将无法解密(解密函数会针对"看似加密但密钥错误"的数据抛出配置检查提示),因此在已有数据的环境上切勿随意改动该变量。
  3. 登录密码用于保护 Web 界面与 API:设置OPEN_NOTEBOOK_PASSWORD即启用了内置密码认证;未设置时认证完全禁用(本地/内网零配置场景可用)。公网部署务必通过表单或环境变量设置强密码。
  4. 升级方式:把模板输入项appServiceImage从默认的lfnovo/open_notebook:1.10.0改为更新的发布标签后重新部署即可完成镜像升级;容器内/app/data与数据库卷中的数据会随卷保留。
  5. 仅暴露前端端口:模板刻意不向数据库服务配置域名,公网入口只有映射到 8502 的应用域名,后端 5055 仅在容器内部被 Next.js 代理访问,外部无法直接触达,减小了攻击面。

与官方 Docker Compose 部署的对照

如果你想在 EasyPanel 之外使用传统编排方式,仓库提供了等价的参考实现:

  • docker-compose.yml:标准的双容器部署(surrealdb + open_notebook),环境变量集合与 EasyPanel 模板几乎一一对应(SURREAL_URL使用服务名ws://surrealdb:8000/rpc),可作为理解 EasyPanel 模板字段含义的权威对照;
  • examples/docker-compose-single.yml:单容器形态(不推荐用于生产,README 亦标注为 deprecated),需要把SURREAL_URL覆盖为ws://localhost:8000/rpc
  • 完整的环境变量参考见 docs/5-CONFIGURATION/environment-reference.md,安装总览见 docs/1-INSTALLATION/index.md。

综上,这套 EasyPanel 模板把 Open Notebook 的"应用 + SurrealDB"部署浓缩为一个表单、一次点击:meta.yaml定义人机交互的表单,index.ts负责把表单翻译成包含随机密钥、内部网络寻址、持久化卷与反向代理友好配置的两个服务。理解了OPEN_NOTEBOOK_PASSWORDOPEN_NOTEBOOK_ENCRYPTION_KEYAPI_URL/INTERNAL_API_URL/SURREAL_*这组环境变量的作用,你就能在任何支持 EasyPanel 的自托管主机上,稳定、安全地跑起一套属于自己的 Open Notebook 研究空间。

【免费下载链接】open-notebookAn Open Source implementation of Notebook LM with more flexibility and features项目地址: https://gitcode.com/GitHub_Trending/op/open-notebook

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 21:16:19

同日宣告:OpenAI称AGI到来,美国国会提案将开发超级AI列为刑事罪

2026年9月3日&#xff0c;两件事同天发生&#xff0c;将AI行业推入一个过去11年从未面对过的处境&#xff1a;OpenAI总裁格雷格布罗克曼在媒体电话会议上宣布"欢迎来到AGI时代"&#xff0c;而同一天&#xff0c;美国参议员伯尼桑德斯与众议员格雷格卡萨联合提出《禁止…

作者头像 李华
网站建设 2026/9/10 21:14:11

PyTorch张量基础:深度学习中的多维数组操作

1. PyTorch张量基础&#xff1a;深度学习世界的基石 在深度学习领域&#xff0c;PyTorch张量就像建筑工地上的砖块&#xff0c;是构建一切复杂模型的基础材料。我刚开始接触PyTorch时&#xff0c;花了大量时间理解张量的本质&#xff0c;现在回头看&#xff0c;这段基础打牢后&…

作者头像 李华