NoteGenNOTEGEN.

自托管部署

使用 Docker Compose 部署 NoteGen Server,并完成 HTTPS、实例初始化、客户端连接与日常维护。

NoteGen Server 为 NoteGen 提供账号、设备关联、实时同步、团队协作和账号管理服务。本指南面向希望在自己的 Linux 服务器或受信局域网中运行实验实例的用户。

NoteGen Server 当前处于实验阶段,部署方式、配置和数据库结构仍可能变化。请始终保留 NoteGen 本地 Markdown,不要把实验实例作为重要数据的唯一副本。

选择部署方式

方式适合场景需要准备
Docker Compose(推荐)快速体验、个人或小型团队实例Docker Engine、Docker Compose v2
从源码运行阅读实现、调试协议和参与开发Node.js 22+、pnpm 10.20.0、PostgreSQL 17

生产或长期运行的实验实例建议使用 Docker Compose。从源码运行主要用于开发,不建议直接用 pnpm dev 对外提供服务。

使用 Docker Compose 部署

默认 Compose 会启动 NoteGen Server 和 PostgreSQL 17,并使用两个独立的数据卷保存数据库与附件。服务默认只监听宿主机的 127.0.0.1:3789。

官方测试镜像为 ghcr.io/codexu/note-gen-server:beta,支持 linux/amd64 和 linux/arm64,可匿名拉取。服务器无需安装 Node.js 或 pnpm,也无需从源码构建。beta 指向最近发布的测试版,本指南使用该频道部署和升级。

1. 准备服务器

开始前确认:

  • 已安装 Docker Engine 和 Docker Compose v2;
  • 服务器可以访问 ghcr.io;
  • 远程访问时已经准备域名,并能将域名解析到服务器;
  • 防火墙只开放 SSH、HTTP 和 HTTPS,不要开放 PostgreSQL 端口。

2. 下载部署配置

git clone https://github.com/codexu/note-gen-server.git
cd note-gen-server
cp .env.docker.example .env

仓库中的 compose.yaml 是部署拓扑,.env 保存当前实例的配置。不要把真实 .env 提交到 Git。

3. 配置环境变量

分别执行三次以下命令,生成三个不同的随机值:

openssl rand -hex 32

编辑 .env,至少确认以下项目:

变量填写方式
POSTGRES_PASSWORD第一个随机值,仅供当前 PostgreSQL 实例使用
AUTH_SECRET第二个随机值;上线后不要随意更换
SETUP_TOKEN第三个随机值,首次安装时在页面输入;不要放在网址、截图或公开日志中
PUBLIC_BASE_URLNoteGen 客户端实际访问的地址,不带路径和末尾斜杠
SERVER_BIND_ADDRESS保持 127.0.0.1,由反向代理提供公网入口
NOTEGEN_SERVER_IMAGE改为 ghcr.io/codexu/note-gen-server:beta,跟随测试版频道
ACCOUNT_STORAGE_MAX_BYTES单账号同步容量初始值,默认 5 GiB,包含历史和附件预占
INSTANCE_STORAGE_MAX_BYTES实例同步容量初始值,默认 50 GiB;数据库索引、WAL、备份需另行监控
STORAGE_MIN_FREE_BYTES附件磁盘最低预留空间,默认 1 GiB

将 .env 中的镜像配置设为以下值,即使示例文件使用了具体版本,也以此处填写的值为准:

NOTEGEN_SERVER_IMAGE=ghcr.io/codexu/note-gen-server:beta

需要控制升级版本时,可以将 beta 替换为已发布的完整版本标签,或使用 ghcr.io/codexu/note-gen-server@sha256:... 固定镜像 digest。

仅在本机测试时,可以使用:

PUBLIC_BASE_URL=http://127.0.0.1:3789

远程部署必须使用 HTTPS,例如:

PUBLIC_BASE_URL=https://sync.example.com

4. 启动服务

docker compose pull
docker compose up -d
docker compose ps

以上命令拉取 .env 中指定的预构建镜像,并启动服务端、账号管理 Web 和 PostgreSQL。源码容器构建方式见从源码运行。

首次启动会等待 PostgreSQL 就绪,并自动执行尚未应用的数据库迁移。两个服务都显示为 healthy 后,再检查就绪接口:

curl --fail http://127.0.0.1:3789/health/ready

命令成功且接口返回就绪状态,表示容器和数据库已经可以接受请求。如果服务未就绪,先查看常见问题。

5. 配置 HTTPS

远程访问必须在 NoteGen Server 前配置 Caddy、Nginx 或 Traefik。反向代理需要支持:

  • WebSocket Upgrade;
  • Authorization、Range 和 X-Request-Id 请求头;
  • 大于附件分片大小的请求体;
  • /v1/sync/events 的流式响应,不要进行响应缓冲。

Caddy 最小配置示例:

sync.example.com {
  reverse_proxy 127.0.0.1:3789
}

Caddy 会自动申请和续期 HTTPS 证书。开放公网前先确认 SETUP_TOKEN 已设为独立随机值;未初始化实例只有持有该凭据的操作者才能创建首位管理员。确认浏览器通过 https://sync.example.com 打开页面后,再继续初始化。

只有反向代理与容器位于受信网络中,并且公网无法绕过代理直连服务端端口时,才能将 .env 中的 TRUST_PROXY 设置为 true。

6. 初始化实例

在浏览器打开 PUBLIC_BASE_URL,按照安装向导:

  1. 输入 .env 中的 SETUP_TOKEN 安装凭据;
  2. 设置实例名称并创建首位管理员账号;
  3. 登录账号管理页面,确认安装入口已关闭;
  4. 保持关闭注册或改为仅邀请,按需添加测试成员。

安装完成后可以从 .env 移除 SETUP_TOKEN,已有实例不会重新开启安装入口。已有账号的实例升级无需补设安装凭据。

公开注册会增加实例维护和滥用处理成本。个人实例建议保持关闭,需要其他用户时再使用限时邀请。

7. 连接 NoteGen

在 NoteGen 的同步设置中选择 NoteGen Server,填写与 PUBLIC_BASE_URL 完全一致的服务器地址,然后注册或登录。

连接后建议按以下顺序验证:

  1. 在设备 A 新建一篇测试笔记;
  2. 确认设备 B 能收到该笔记;
  3. 让一台设备短暂离线,分别修改测试内容;
  4. 恢复网络,确认同步可以继续且本地 Markdown 仍然存在。

其他 Git、S3、WebDAV 和云盘方案参见同步配置。

容量设置

管理员可在 Web 后台的“实例运维 → 访问与配置 → 运行配置”中修改“每账号容量上限(GiB)”和“实例总容量上限(GiB)”。输入当前密码并保存后立即生效,无需重启;支持小数,最小为 1 MiB。

ACCOUNT_STORAGE_MAX_BYTES 和 INSTANCE_STORAGE_MAX_BYTES 仅在首次安装或旧实例尚未保存容量设置时提供初始值。后台保存后以数据库配置为准,重启不会被环境变量覆盖。

容量包含保留历史和附件上传预占,共享资料库计入所有者账号。降低上限不会删除已有数据;超限后限制新增占用,读取、删除和取消上传仍可使用。删除笔记不会立即释放全部容量,数据库索引、WAL 和备份仍需单独预留磁盘空间。

升级实例

升级前先阅读新版本说明,并对 PostgreSQL 与附件数据建立同一时间点的配套备份。使用 beta 频道时,无需每次修改镜像标签,执行以下命令即可拉取并应用最近发布的测试版。保留现有 .env 中的密码、密钥和实例地址,不要用示例文件覆盖它。

cd note-gen-server
git pull --ff-only
docker compose pull
docker compose up -d
docker compose ps

服务启动时会执行数据库迁移。升级后重新检查:

curl --fail http://127.0.0.1:3789/health/ready
docker compose logs --tail=200 server

发布新的测试版不会自动更新正在运行的容器;执行 docker compose pull 和 docker compose up -d 后才会应用更新。如果使用完整版本或 digest,升级前需先修改 .env 中的 NOTEGEN_SERVER_IMAGE。若数据库迁移已执行,回退前应按备份与恢复手册恢复配套数据,不能只切换回旧镜像。

数据与备份

默认部署的数据分为两部分:

数据默认位置
账号、设备、同步游标和对象版本Docker 的 postgres_data Volume
附件、Blob 与服务端生成的数据Docker 的 notegen_data Volume

备份必须同时覆盖 PostgreSQL 和 notegen_data,并在隔离环境验证恢复。只保存其中一部分不能视为完整备份。

文件系统部署已经提供离线备份、签名校验和新实例恢复命令,操作顺序见仓库的备份与恢复手册。请先按手册在隔离环境完成恢复,再开放测试。备份归档目前不加密,必须存放在受限位置并另存异机副本。S3 数据不能套用文件系统恢复命令。

当前仅支持单服务副本部署。容量预算不包括数据库索引、WAL 和备份目录,仍需配置磁盘告警。

停止容器但保留数据:

docker compose down

不要在仍需保留数据时执行 docker compose down -v,-v 会请求删除 Compose 管理的数据卷。

日常维护

查看容器状态与最近日志:

docker compose ps
docker compose logs --tail=200 server
docker compose logs --tail=200 postgres

持续查看服务端日志:

docker compose logs -f server

检查服务能力与健康状态:

curl --fail http://127.0.0.1:3789/health/ready
curl --fail http://127.0.0.1:3789/v1/capabilities

从源码运行

源码模式适合开发者调试和贡献代码。先安装 Node.js 22 或更高版本、pnpm 10.20.0 和 PostgreSQL 17,然后执行:

git clone https://github.com/codexu/note-gen-server.git
cd note-gen-server
createuser notegen
createdb -O notegen notegen
pnpm install
cp .env.example .env
pnpm dev

修改 .env 中的 DATABASE_URL、AUTH_SECRET、首次安装的 SETUP_TOKEN 和 PUBLIC_BASE_URL。开发模式下 API 默认监听 3789,账号管理 Web 默认监听 3790。

项目结构、修改边界和贡献检查参见 NoteGen Server 仓库中的贡献指南。

从源码构建容器

需要验证本地修改时,在仓库根目录准备 .env:尚无配置时复制 .env.docker.example 并填写实例配置;已有配置则保留原文件。将 NOTEGEN_SERVER_IMAGE 改为 notegen-server:dev,再执行:

docker compose -f compose.yaml -f compose.dev.yaml up -d --build

修改源码后重新执行该命令即可构建更新。需要复现构建时,记录对应的 Git 提交 SHA。

常见问题

现象检查与处理
镜像拉取失败确认服务器可以访问 ghcr.io,并检查代理或 DNS 配置
PostgreSQL 一直不健康查看 docker compose logs --tail=200 postgres,确认磁盘空间和 POSTGRES_PASSWORD
Server 一直不健康查看服务端日志,确认数据库已就绪且 .env 中必填项不为空
浏览器可以打开,但客户端无法连接确认客户端地址与 PUBLIC_BASE_URL 完全一致,并检查 HTTPS 证书
实时同步没有触发检查反向代理是否支持 WebSocket Upgrade
上传附件返回 413提高反向代理的请求体大小限制
重启后无法正常登录确认没有更换 AUTH_SECRET,并检查服务器时间是否准确

提交问题时,请附上操作系统与 CPU 架构、部署方式、镜像标签、反向代理类型、复现步骤和脱敏后的容器日志。不要公开 .env、Token、密码或恢复密钥。

部署检查清单

  • POSTGRES_PASSWORD 和 AUTH_SECRET 使用不同的随机值;
  • PUBLIC_BASE_URL 与客户端实际地址一致;
  • 公网访问使用有效的 HTTPS 证书;
  • PostgreSQL 和服务内部端口没有直接暴露到公网;
  • 反向代理支持 WebSocket 和较大的附件请求;
  • PostgreSQL 与附件数据采用配套备份;
  • 本地 Markdown 仍然保留,并完成至少一次多设备同步验证。