自建笔记这件事,很多人卡在同一个地方:云笔记的同步很省心,但数据不在自己手里;群晖 Note Station 这类方案体验不错,却绑定在特定硬件生态上;自己用文件夹加 Markdown 编辑器拼一套,又很快在搜索、版本、多端同步和任务管理上散架。nowen-note(弄文笔记)正是冲着这个夹缝来的——一个可自托管的私有知识库,定位上对标群晖 Note Station,用 Docker 部署,数据落在自己的磁盘上。它提供富文本与 Markdown 双编辑器(Tiptap 3 + CodeMirror 6)、AI 写作助手、思维导图、任务管理、基于 FTS5 的全文搜索和多级笔记本,技术栈是 React 18 + Hono + SQLite,许可证为 GPL-3.0。对开发者、内容创作者和需要内部知识库的小团队来说,它解决的不是"再做一个笔记 App",而是"把知识库的所有权和运维权拿回来"。

它适合谁,不适合谁
nowen-note 的核心价值在于"私有化 + 一体化"。如果你的需求是个人或小团队的知识沉淀,希望笔记、任务、思维导图和 AI 问答在同一个工作区里打通,并且你愿意自己维护一台常开的机器(NAS、迷你主机、VPS 都行),那它值得一试。
但有几类情况需要先想清楚。第一,它是单机 SQLite 架构,不是分布式数据库,这意味着它更适合几十人以内、以读多写少为主的知识库场景,而不是高并发协作平台。第二,GPL-3.0 是强 copyleft 许可证,如果你打算把它集成进闭源商业产品再分发,需要先确认合规边界。第三,自托管意味着备份、升级、安全都是你自己的责任——这也是本文重点展开的部分。
部署前的环境准备
在写 compose 文件之前,先把三件事定下来。
主机与 Docker。 需要一台安装了 Docker Engine 和 Docker Compose v2 的机器。NAS 用户通常可以直接在套件中心或应用市场装好;Linux 服务器上按官方文档安装即可。确认 docker compose version 能正常输出。
数据目录。 提前规划一个持久化目录,例如 /opt/nowen-note/data。这个目录会承载数据库文件和附件,务必放在有备份策略、容量充足的位置,不要用容器内临时层。目录属主需要与容器内运行用户匹配,否则会出现启动后无法写入的问题。
端口与访问方式。 决定服务监听哪个端口,以及是只在内网访问还是要经反向代理对外。如果走公网,请提前准备好域名和 HTTPS 证书,不要用明文 HTTP 直接暴露。
Docker Compose 启动
仓库中提供了 docker-compose.yml,同时也有发布到 Docker Hub 的镜像 cropflre/nowen-note。两种方式都可行:直接拉取镜像更省事,本地 build 则适合你想改代码或构建 ARM 镜像的情况(例如在 x86 主机上为 A311D、RK3566 这类板子构建 arm64 镜像,可以用 buildx)。
下面是一份结构示意,字段名和默认值请以仓库中的 docker-compose.yml 与部署文档为准:
services:
nowen-note:
image: cropflre/nowen-note:latest
container_name: nowen-note
restart: unless-stopped
ports:
- "${NOWEN_PORT}:3000"
environment:
- TZ=${TZ}
- PUBLIC_WEB_ORIGIN=${PUBLIC_WEB_ORIGIN}
- JWT_SECRET=${JWT_SECRET}
- BACKUP_DIR=${BACKUP_DIR}
volumes:
- ./data:/app/data
建议把易变的值放进同目录的 .env 文件,而不是硬编码在 compose 里,这样升级和迁移时更清晰。启动与查看日志:
docker compose up -d
docker compose logs -f --tail=100
首次启动后,用浏览器访问 http://主机IP:端口。如果容器反复重启,优先看日志里是不是数据目录权限或端口占用的问题。
几个关键环境变量的实际影响
| 变量 | 影响范围 | 注意点 |
|---|---|---|
NOWEN_PORT | 对外暴露的访问端口 | 与反向代理、防火墙规则保持一致;改端口后旧书签会失效 |
TZ | 每日记录、任务时间、日志时间戳 | 不设置容易导致"今天"错位、定时任务时间偏移 |
PUBLIC_WEB_ORIGIN | 分享链接、回调地址、跨域判断 | 反向代理场景下若仍指向 localhost,分享出去的链接会打不开 |
JWT_SECRET | 登录会话令牌的签名密钥 | 必须是足够长的随机串;一旦更换,所有已登录会话会失效 |
BACKUP_DIR | 备份文件的输出位置 | 应指向容器外可持久化、可被外部备份工具抓取的目录 |
其中 JWT_SECRET 最容易被忽视。用默认值或弱口令,等于把会话伪造的门槛降到很低;而它一旦泄露,攻击者不需要知道你的密码就能构造有效令牌。生成方式可以用 openssl rand -base64 48 之类的命令,并且不要提交进版本库。
首次登录:为什么必须立刻改密码
部署文档里写得很明确:默认管理员账号是 admin / admin123,首次登录后请立即修改密码。原因不复杂——这个默认凭据是公开写在文档和仓库里的,任何能访问到你服务端口的人都知道它。自托管服务通常先从局域网起步,很多人会顺手做端口映射或反代,一旦暴露到公网,默认密码就等于把门敞开。
所以首次登录后应该按这个顺序处理:修改管理员密码为强密码;确认 JWT_SECRET 已替换为随机值;如果暂时不需要外网访问,先在路由器或防火墙层面关掉端口映射;需要外网时,用反向代理加 HTTPS,并把 PUBLIC_WEB_ORIGIN 设置为真实的外部地址。

备份:自托管的底线
SQLite 架构的好处是备份简单——核心就是数据目录。但要备份得可靠,有几个细节值得注意。
备份什么。 至少包括数据库文件和附件/上传目录。只备份数据库而漏掉附件,恢复后笔记里的图片和文件会全部断链。
怎么备份。 最稳妥的方式是在容器停止状态下复制数据目录,或者使用 SQLite 的在线备份机制(如 .backup 命令)来保证一致性。直接对正在写入的数据库文件做文件级复制,存在拿到损坏副本的风险。如果配置了 BACKUP_DIR,可以把备份产物指向一个宿主机上的独立目录,再交给 restic、Borg、rsync 或 NAS 自带的快照工具做异地/离线副本。
多久备一次。 知识库的写入频率通常不高,每日一次加保留多个历史版本已经够用。关键是做一次恢复演练——很多人备份了半年,真出事时才发现压缩包解不开或路径写错。
升级与回滚
升级前先备份,这是没有例外的规则。流程大致是:拉取新镜像、重建容器、观察日志确认数据库迁移正常。
docker compose pull
docker compose up -d
docker compose logs -f --tail=200
需要注意两点。一是版本跨度大时,数据库结构可能发生变化,降级回旧镜像未必能读回新结构,所以回滚的前提是"升级前的备份还在"。二是如果使用本地 build 而不是镜像,记得先重新构建再重建容器,否则跑的还是旧代码。
公网访问的边界与常见故障
把 nowen-note 放到公网并非不行,但要清楚边界:它不是一个以抗攻击为首要目标的边缘服务,暴露前应至少有 HTTPS、强密码、随机 JWT_SECRET、访问控制(如仅允许特定 IP 或加一层身份网关)和定期备份。更保守的做法是只通过 VPN 或内网访问,把公网入口降到最小。
几个高频问题及排查方向:
- 打不开页面:先看容器是否在运行(
docker compose ps),再看端口是否被占用、防火墙是否放行。 - 能登录但立刻掉线:多半是
JWT_SECRET在重启后发生了变化,或者多实例部署时各实例密钥不一致。 - 分享链接指向 localhost:反向代理场景下
PUBLIC_WEB_ORIGIN没设成外部域名。 - 时间不对:
TZ未设置或设置错误,影响每日记录和任务时间。 - 恢复后附件丢失:备份时只包含了数据库,漏掉了附件目录。
落地建议
nowen-note 的吸引力在于把笔记、任务、思维导图和 AI 写作放进一个可自托管的私有空间里,代价是你需要承担运维责任。比较务实的落地顺序是:先在内网用 Docker Compose 跑起来,改掉默认密码、设好 JWT_SECRET 和 TZ;然后建立每日备份并做一次恢复演练;确认稳定后,再考虑是否通过反向代理对外,并同步收紧访问控制。项目仍在活跃迭代,部署前建议对照仓库中的 docker-compose.yml 与部署文档核验最新字段与版本,许可证 GPL-3.0 的相关义务也应在二次分发前确认清楚。

评论列表 (1条):
加载更多评论 Loading...