flatnotes v5.5.5 Docker Compose 部署指南

使用 Docker Compose 部署 flatnotes v5.5.5:官方镜像选型与国内拉取实测、compose 编排、数据持久化、环境变量表、等价 docker run、运维命令与常见问题全流程实录。

flatnotesflatnotes笔记知识库2026/10/30

flatnotes v5.5.5 Docker Compose 部署指南

目标:在一台 Linux 服务器上用 Docker Compose 部署 flatnotes v5.5.5(单用户无数据库 Markdown 笔记应用),覆盖镜像选型与国内拉取实测、compose 编排、登录验证、数据持久化、环境变量、等价 docker run、日常运维命令与常见问题排查。全流程已在 Ubuntu 22.04 服务器实测通过。

一、环境信息

项目值
操作系统Ubuntu 22.04
Docker29.9.2
Docker Composev5.6.1(docker compose 插件)
flatnotes 版本v5.5.5(2026-08-29 发布,GitHub Releases 实查)
镜像dullage/flatnotes:v5.5.5(摘要 sha256:ca4b40ee7491aabf6b52bbb20ab140145cb96981d4b3fe96ab1e797ac6cd93e5)
服务端口8143(宿主)→ 8080(flatnotes 默认监听)
数据目录/opt/flatnotes/data(挂载到服务内 /data)
演示账号admin / q1w2e3r4
资源占用实测空载内存约 48 MiB,镜像体积 384 MB

二、镜像选型说明

flatnotes 官方 README 明确「自托管推荐使用 Docker」,镜像发布在 Docker Hub 的 dullage/flatnotes 命名空间(与代码仓库同名,由作者本人维护)。

版本标签如何选(2026-10-30 实查镜像标签清单):

标签含义建议
v5.5.5具体版本号生产推荐,升级可控
latest最新稳定版图省事可用,升级时间不可控
develop开发分支构建仅测试用途,勿用于生产

⚠️ 注意:网上旧教程里常见的 b4bz/flatnotes 是早期第三方维护的镜像命名空间,官方 README 现已统一指向 dullage/flatnotes;且标签带 v 前缀(如 v5.5.5),不带 v 的 5.5.5 标签不存在——2026-10-30 实查拉取 b4bz/flatnotes:5.5.5 与 dullage/flatnotes:5.5.5 均返回 not found,原因即命名空间迁移与标签拼写。

该镜像内置健康检查(启动后状态会显示 healthy)、以非 root 用户(PUID/PGID,默认 1000)运行应用进程,数据目录固定为 /data。

三、前置条件

  1. 服务器已安装 Docker 与 Compose 插件:
docker --version
docker compose version

实测输出(节选):

Docker version 29.9.2, build a82e528
Docker Compose version v5.6.1
  1. 规划目录并确认 8143 端口空闲:
mkdir -p /opt/flatnotes/data
ss -ltn | grep ':8143' || echo "8143 空闲"

实测输出:

8143 空闲
  1. 出网可用(拉取镜像用);若走国内镜像源,见「十、常见问题」第 1 条。

四、部署步骤

4.1 编写 docker-compose.yml

在 /opt/flatnotes/ 下创建编排文件:

cd /opt/flatnotes

docker-compose.yml 完整内容:

name: flatnotes-v5.5.5-stack

services:
  flatnotes:
    image: dullage/flatnotes:v5.5.5
    container_name: flatnotes-v5.5.5-web
    hostname: flatnotes
    restart: unless-stopped
    ports:
      - "8143:8080"
    environment:
      FLATNOTES_AUTH_TYPE: "password"
      FLATNOTES_USERNAME: "admin"
      FLATNOTES_PASSWORD: "q1w2e3r4"
      FLATNOTES_SECRET_KEY: "fN2k8sVq6TzR4mWx9pLb3Jh7Yd5Gc1Ne"
    volumes:
      - /opt/flatnotes/data:/data
    networks:
      - flatnotes-net

networks:
  flatnotes-net:
    name: flatnotes-v5.5.5-net
    driver: bridge
    ipam:
      config:
        - subnet: 10.89.72.0/24

逐项说明:

  • name: 固定项目名,避免多套 compose 项目同名导致互相误删;
  • FLATNOTES_SECRET_KEY 是登录会话 Token 的签名密钥(JWT HS256),生产务必换成自己的长随机串(生成方式见 4.2);更换后所有已登录会话立即失效;
  • ports 把服务默认的 8080 映射到宿主 8143,可按需替换为其他空闲端口;
  • volumes 把宿主 /opt/flatnotes/data 挂载为数据目录 /data,笔记 .md 文件、附件、搜索索引都落在这里,重建服务不丢数据;
  • networks 使用独立自定义网段,避免与宿主内其他网络冲突;没有多服务编排诉求时也可以整体删掉 networks 两段,使用默认网络。

4.2 生成会话签名密钥(生产必做)

openssl rand -base64 24 | tr -d '+/='

实测输出:

wUoAsBILnl2IexXkizV1p6JvT99qvHe

把输出的随机串填入 FLATNOTES_SECRET_KEY。

4.3 拉取镜像并启动

cd /opt/flatnotes
docker compose pull
docker compose up -d

实测输出:

 Container flatnotes-v5.5.5-web Created
 Container flatnotes-v5.5.5-web Started

启动日志(docker compose logs flatnotes,节选):

======================================
======== Welcome to flatnotes ========
======================================

If you enjoy using flatnotes, please
consider sponsoring the project at:

https://sponsor.flatnotes.io

It would really make my day 🙏.

──────────────────────────────────────

Setting file permissions...
Starting flatnotes as user 1000...
2026-10-29 17:40:16 [INFO]: Creating new index
2026-10-29 17:40:16 [INFO]: Index synchronized
2026-10-29 17:40:16 [INFO]: Replacing href value for base element in 'client/dist/index.html' with '/'.
INFO:     Started server process [1]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://0.0.0.0:8080 (Press CTRL+C to quit)

关键行解读:Setting file permissions... 表示按 PUID/PGID 修正数据目录属主;Creating new index / Index synchronized 表示首次启动建立 Whoosh 搜索索引;最后一行说明服务已在容器内 8080 端口就绪。

4.4 验证部署

确认运行状态与健康检查:

docker compose ps

实测输出:

NAME                    IMAGE                       COMMAND         SERVICE    STATUS                    PORTS
flatnotes-v5.5.5-web    dullage/flatnotes:v5.5.5    "/entrypoint.sh"  flatnotes  Up 8 seconds (healthy)   0.0.0.0:8143->8080/tcp, [::]:8143->8080/tcp

健康检查端点实测:

curl http://localhost:8143/health

实测输出:

"OK"

浏览器访问 http://<服务器IP>:8143,出现 flatnotes 登录页,用 admin / q1w2e3r4 登录后即进入首页,首页会显示 RECENTLY MODIFIED(最近修改)快捷区块。界面概览与更多截图说明见《flatnotes 介绍与选型指南》。

五、数据持久化说明

flatnotes 无数据库,/data 目录就是全部状态。部署后数据目录结构实测如下:

ls -la /opt/flatnotes/data

实测输出:

total 24
drwxr-xr-x 4 1000 1000 4096 Oct 29 17:42 .
drwxr-xr-x 1 root root 4096 Oct 29 17:40 ..
drwxr-xr-x 2 1000 1000 4096 Oct 29 17:42 .flatnotes
-rw-r--r-- 1 1000 1000  126 Oct 29 17:41 Nginx 配置片段.md
drwxr-xr-x 2 1000 1000 4096 Oct 29 17:42 attachments
-rw-r--r-- 1 1000 1000  161 Oct 29 17:42 服务器巡检手册(v2).md

三部分内容:

路径内容是否可删
*.md每篇笔记一个纯 Markdown 文件,文件名即笔记标题不可删,这是全部笔记数据
attachments/上传的附件原件不可删(除非确认放弃附件)
.flatnotes/Whoosh 全文搜索索引(缓存性质)可删,重启后自动重建(实测日志 Creating new index)

重启持久化实测:写入两篇笔记后执行 docker compose restart,重启完成再次读取,笔记标题、内容、修改时间戳均不变,登录会话 Token 也仍然有效(Token 由 FLATNOTES_SECRET_KEY 签发,服务重建不影响校验)。

💡 技术拓展:搜索索引缓存与数据源的分离是「纯文件存储」类组件的常见设计,同类对比——flatnotes 把索引放在数据目录内的 .flatnotes/ 子目录;SilverBullet 把索引放在服务端空间(可通过同步排除);Trilium 则把数据与索引统一放数据库。flatnotes 这种「索引是缓存、文件是真相」的设计,允许你在服务运行期间直接在磁盘上增删改 .md 文件,索引会在每次搜索时增量同步(官方 README 明确说明)。

六、环境变量表

部署层环境变量(镜像 entrypoint 与 Dockerfile 定义,v5.5.5 实查):

变量默认值说明
PUID / PGID1000 / 1000应用进程运行身份,启动时按其修正 /data 属主
FLATNOTES_AUTH_TYPEpassword认证模式:none / read_only / password / totp
FLATNOTES_USERNAME无(password/totp 模式必填)登录用户名(统一按小写比对)
FLATNOTES_PASSWORD无(password/totp 模式必填)登录密码;TOTP 模式下实际校验「密码+动态码」拼接
FLATNOTES_SECRET_KEY无(password/totp 模式必填)会话 Token 的 JWT 签名密钥
FLATNOTES_TOTP_KEY无(totp 模式必填)TOTP 共享密钥,启动时打印二维码供验证器扫码
FLATNOTES_PORT8080服务内监听端口
FLATNOTES_HOST0.0.0.0服务内监听地址
FLATNOTES_PATH/data数据目录

全部参数的默认值、取值约束与生效机制(会话有效期、路径前缀、首页快捷访问区块等),见《flatnotes v5.5.5 配置参数详解》。

七、配置参数说明

最小可用的密码登录形态只需 4 个应用参数(见 4.1),其余保持默认。几个关键项的取舍:

  • FLATNOTES_SECRET_KEY:生产必须换随机值。它同时是登录会话的有效期锚点(Token 内含过期时间,默认 30 天,可用 FLATNOTES_SESSION_EXPIRY_DAYS 调整);
  • FLATNOTES_AUTH_TYPE: none:完全放开访问(接口也不鉴权),只适合纯内网信任环境;read_only 则放行读接口、拦截写接口,适合做只读资料站;
  • FLATNOTES_AUTH_TYPE: totp:在密码之外叠加 TOTP 动态码,登录时密码与 6 位动态码拼接传入(如 q1w2e3r4123456)。部署形态与验证方法见《flatnotes v5.5.5 配置参数详解》的认证参数一节。

八、配置文件挂载

flatnotes 没有配置文件,所有配置都是环境变量(官方 Wiki《Environment Variables》明确)。因此需要挂载的只有数据目录一项:

    volumes:
      - /opt/flatnotes/data:/data          # 必须:笔记/附件/索引
      # - /opt/flatnotes/index:/data/.flatnotes   # 可选:把搜索索引单独落位

把索引单独挂出来的价值:备份笔记时可以排除索引目录(减小体积),索引损坏时也可单独清理而不触碰笔记文件。索引目录内容实测(Whoosh 格式):

5_WRITELOCK
5_g4bcan3hbrlft61o.seg
_5_5.toc

九、等价 docker run

与 4.1 编排等价的单命令启动(照录官方 README 形态,端口与数据目录替换为本文取值):

docker run -d \
  --name flatnotes-v5.5.5-web \
  -e "PUID=1000" \
  -e "PGID=1000" \
  -e "FLATNOTES_AUTH_TYPE=password" \
  -e "FLATNOTES_USERNAME=admin" \
  -e "FLATNOTES_PASSWORD=q1w2e3r4" \
  -e "FLATNOTES_SECRET_KEY=fN2k8sVq6TzR4mWx9pLb3Jh7Yd5Gc1Ne" \
  -v "/opt/flatnotes/data:/data" \
  -p "8143:8080" \
  --restart unless-stopped \
  dullage/flatnotes:v5.5.5

与 compose 方案的取舍:单命令适合快速验证,长期运行建议 compose(声明式、可版本化、升级只需改 tag)。

十、常用运维命令

以下命令均在 /opt/flatnotes/ 目录下执行。

状态与健康:

docker compose ps                 # 运行状态(含 healthy 健康检查结果)
curl http://localhost:8143/health # 业务健康检查,输出 "OK"

日志查看:

docker compose logs --tail 50 flatnotes   # 最近 50 行日志
docker compose logs -f flatnotes          # 跟随输出

重启与停止:

docker compose restart   # 重启服务,数据不受影响
docker compose down      # 停止并删除服务(数据在宿主 /opt/flatnotes/data,不受影响)
docker compose up -d     # 再次拉起

备份与恢复(纯文件目录,直接打包即可):

tar -czf /opt/flatnotes/notes-backup.tar.gz -C /opt/flatnotes/data .

实测输出(无报错即成功,确认包文件存在):

ls -la /opt/flatnotes/notes-backup.tar.gz
-rw-r--r-- 1 root root 6867 Oct 30 01:47 /opt/flatnotes/notes-backup.tar.gz

恢复时解包回 /opt/flatnotes/data 并重启服务。更多基于数据目录的日常操作(直读检索、附件管理、接口自检)见《flatnotes v5.5.5 常用工具与 API 详解》。

升级到新版本:先到官方 Releases 页(https://github.com/dullage/flatnotes/releases)确认最新稳定 tag,然后分两步操作——

# 1) 编辑 docker-compose.yml:把 image 行的版本标签由 v5.5.5 改为 Releases 页公告的最新稳定 tag
# 2) 拉取新镜像并重建服务
docker compose pull && docker compose up -d

回滚即把 tag 改回旧版本重新 up -d;由于数据全部是 .md 文件,版本回滚不存在数据结构迁移问题。

十一、常见问题(FAQ)

Q1:docker compose pull 报「this image is not in the allowlist」或 not found?

直连 Docker Hub 不可用的环境下,国内镜像加速器可能拦下该镜像(实测现象:error from registry: … 这镜像不在白名单. this image is not in the allowlist.)。实测可用渠道为前缀式镜像源拉取:

docker pull docker.1ms.run/dullage/flatnotes:v5.5.5

实测输出:

Digest: sha256:ca4b40ee7491aabf6b52bbb20ab140145cb96981d4b3fe96ab1e797ac6cd93e5
Status: Downloaded newer image for docker.1ms.run/dullage/flatnotes:v5.5.5

拉取成功后打上标准标签再正常编排即可:

docker tag docker.1ms.run/dullage/flatnotes:v5.5.5 dullage/flatnotes:v5.5.5

注意两点:镜像命名空间已迁移到 dullage(旧的 b4bz 教程镜像已不适用);标签带 v 前缀,5.5.5 不是有效标签。另可核对镜像摘要与官方一致(sha256:ca4b40ee…)确认内容可信。

Q2:登录报 Invalid login details.?

实测确认三类原因:密码输错;FLATNOTES_PASSWORD 与登录输入不一致(password 与 totp 模式该变量都必填);TOTP 模式下只输密码没拼动态码。另注意用户名不区分大小写(服务端统一按小写比对),密码区分。

Q3:改了 FLATNOTES_SECRET_KEY 后所有端都要求重新登录?

正常现象。该密钥用于会话 Token 签名,换密钥后旧 Token 全部校验失败,重新登录即可;这也正是轮换该密钥「强制下线全部会话」的用法。

Q4:创建笔记报 409 Cannot create note. A note with the same title already exists.?

flatnotes 以标题作为文件名,标题即唯一键。换一个标题,或用 PATCH 接口/界面编辑原笔记。标题还不能包含 < > : " / \ | ? * 字符,否则接口返回 422 参数校验错误。

Q5:正文里的 #中文标签 搜索不到?

标签识别仅支持英文字母/数字/下划线/连字符(正则 [a-zA-Z0-9_-]+)。中文关键词请直接用全文搜索;英文标签可用 #tag 形式在搜索框检索(会命中标签字段并返回 tagMatches),详见《flatnotes v5.5.5 常用工具与 API 详解》搜索一节。

Q6:想让服务跑在 HTTPS 下?

flatnotes v5.5.5 本身不提供 TLS 配置项,标准做法是在前置反向代理上终结 TLS,再转发到 8143 端口。

十二、参考链接

本系列其他篇章: