Trilium v0.106.0 Docker Compose 部署指南
Trilium v0.106.0 在 Ubuntu 22.04 上的 Docker Compose 从零部署实录:镜像选型、初始化(新建/同步服务器)、健康验证、数据持久化、环境变量与升级回滚演练,全部命令与回显实测。
Trilium v0.106.0 Docker Compose 部署指南
目标:在一台 Ubuntu 22.04 服务器上用 Docker Compose 从零部署 Trilium(TriliumNext/Trilium)v0.106.0 自托管笔记服务器,覆盖镜像选型、初始化(新建/同步服务器两种模式)、数据持久化验证、升级与回滚。已在 Ubuntu 22.04 + Docker 29.8.1 + Compose v5.5.1 环境实测通过:服务监听 8139 端口、数据目录 /opt/trilium/data,健康检查、重启重建与升级演练全部验证成功。组件背景与选型见 《Trilium 介绍与选型指南》。
一、环境信息
- 操作系统:Ubuntu 22.04(x86_64)。
- Docker:
Docker version 29.8.1, build 4a63305;Docker Compose:Docker Compose version v5.5.1(docker --version、docker compose version实测回显)。 - Trilium 版本:v0.106.0(官方最新稳定版,2026-09-25 发布;镜像构建元数据
org.opencontainers.image.version=v0.106.0)。 - 服务端口:宿主机 8139 → 服务 8080(本机实验环境统一规划 8128–8152 段,按需可改)。
- 数据目录:
/opt/trilium/data(bind mount 到服务内/home/node/trilium-data)。 - 部署形态:单服务编排,无外部数据库依赖(数据落 SQLite
document.db)。
二、镜像选型说明
Trilium 官方在 Docker Hub 维护多套镜像,选型依据如下(来源:官方 Docker 安装文档与仓库 compose 文件,2026-10-22 查询):
| 镜像 | 特点 | 适用 |
|---|---|---|
triliumnext/trilium:<版本> | 官方主镜像,AMD64 / ARMv7 / ARM64-v8 三架构,容器内以 node 用户运行(entrypoint 用 su-exec 降权) | 常规自托管部署(本文采用) |
triliumnext/notes:rootless | 官方 rootless 变体,通过 TRILIUM_UID/GID 以任意非特权用户运行 | 禁止 root 运行的托管环境 |
triliumnext/trilium(Alpine 变体) | rootless compose 中以 TRILIUM_VARIANT=alpine 启用的 Alpine 底座 | 追求更小镜像体积 |
tag 策略:官方 compose 文件注释明确提醒 "Using latest may cause unintended updates to the container"(使用 latest 可能引发非预期升级)。生产部署必须锚定版本 tag(如 v0.106.0),升级时手动改 tag,避免自动跟随 latest 出现数据库 sync 版本跨代问题。
实测拉取(docker pull triliumnext/trilium:latest,镜像即 v0.106.0):
Digest: sha256:be93e82699b12950ac4e2e7b565ce092fe215b8dd6ddfc47921e37b49e6a0e8b
Status: Downloaded newer image for triliumnext/trilium:latest
docker.io/triliumnext/trilium:latest
镜像大小实测 513 MB,内置运行时 Node.js v24.21.0。关键元数据(docker inspect 实测):version=v0.106.0、build=2026-09-25T18:09:40.802Z、licenses=AGPL-3.0。
三、前置条件
- 已安装 Docker Engine 与 Compose v2 插件(验证命令与回显):
docker --version && docker compose version
Docker version 29.8.1, build 4a63305
Docker Compose version v5.5.1
- 确认目标端口未被占用(以 8139 为例,无输出即空闲):
ss -ltn | grep 8139
(实测部署后再次执行,出现监听行即服务已起:)
LISTEN 0 4096 0.0.0.0:8139 0.0.0.0:*
LISTEN 0 4096 [::]:8139 [::]:*
- 规划数据目录并确认磁盘余量(Trilium 单库 SQLite,10 万条笔记量级亦在 GB 以内):
mkdir -p /opt/trilium/data
df -h /opt/trilium | tail -1
786G total, 409G avail
四、部署步骤
4.1 编写 docker-compose.yml
在部署目录(本文取 /opt/trilium/compose/)创建 docker-compose.yml。骨架沿用官方 v0.106.0 仓库根 compose 文件,锚定版本 tag 并显式声明项目名:
name: trilium-0.106.0-stack
services:
trilium:
image: triliumnext/trilium:v0.106.0
container_name: trilium-app
restart: unless-stopped
environment:
- TRILIUM_DATA_DIR=/home/node/trilium-data
ports:
- '8139:8080'
volumes:
- /opt/trilium/data:/home/node/trilium-data
- /etc/localtime:/etc/localtime:ro
networks:
trilium-net:
driver: bridge
ipam:
config:
- subnet: 10.89.71.0/24
要点说明:
name:显式指定 Compose 项目名,避免多套部署同名目录互相干扰;⚠️ 实测 Docker Compose 会把项目名中的点规范化:trilium-0.106.0-stack实际生效为trilium-01060-stack(见下文docker compose down回显),属正常现象。image:锚定v0.106.0,升级流程见十、10.3 节。TRILIUM_DATA_DIR指向数据目录,与 volumes 的容器侧路径保持一致;宿主侧/opt/trilium/data需可写(容器内 entrypoint 会chown为 node 用户)。/etc/localtime只读挂载让笔记时间戳与宿主时区一致(官方 compose 同款做法)。restart: unless-stopped与官方 compose 一致:随服务自启,手动停止后不自动拉起。
4.2 启动服务
docker compose up -d
Container trilium-0.106.0-app Created
Container trilium-0.106.0-app Starting
Container trilium-0.106.0-app Started
等待数十秒后查看状态(镜像自带健康检查:每 60 秒执行一次,启动宽限期 30 秒):
docker compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
trilium-0.106.0-app triliumnext/trilium:v0.106.0 "docker-entrypoint.s…" trilium 20 seconds ago Up 8 seconds (healthy) 0.0.0.0:8139->8080/tcp, [::]:8139->8080/tcp
STATUS 出现 (healthy) 即部署成功。启动日志横幅(docker compose logs trilium | head -12 实测节选):
No USER_UID specified, leaving 1000
No USER_GID specified, leaving 1000
Becca (note cache) load took 17ms
_____ _ _ _
|_ _| __(_) (_)_ _ _ __ ___ | \ | | ___ | |_ ___ ___
| || '__| | | | | | | '_ ` _ \ | \| |/ _ \| __/ _ \/ __|
| || | | | | | |_| | | | | | | |\ | (_) | || __/\__ \
|_||_| |_|_|_|\__,_|_| |_| |_| |_| \_|\___/ \__\___||___/ 0.106.0
📦 Versions: app=0.106.0 db=240 sync=39 clipper=1.0
🔧 Build: 2026-09-25 18:09:29 (c0fdceba3b)
📂 Data dir: /home/node/trilium-data
💻 CPU: Intel(R) Core(TM) i7-14700KF (12-core @ 0 Mhz)
💾 DB size: 3.2 MiB
Listening on port 8080
app=0.106.0 db=240 sync=39 三个版本号是排查客户端/服务器同步兼容性的关键依据。
4.3 服务健康验证
curl -s http://localhost:8139/api/health-check
{"status":"ok"}
返回 {"status":"ok"}(HTTP 200)即服务健康。镜像内置健康检查使用的正是该端点(数据目录 healthcheck-url 文件内容实测为 http://127.0.0.1:8080/api/health-check)。
4.4 初始化:新建文档 / 同步服务器 二选一
浏览器访问 http://<服务器IP>:8139,首次进入会出现官方初始化选择页(来源:官方服务器安装文档,2026-10-22 查询):
- New document(新建文档):本机作为全新知识库或独立同步服务器。个人新装选这个。
- Sync from server(从服务器同步):本机作为已有 Trilium 服务器的从属副本,需填入主服务器地址与同步密码,首次同步会拉取种子数据。
两种模式的判定可通过状态接口实时确认(部署后、初始化前实测):
curl -s http://localhost:8139/api/setup/status
{"isInitialized":false,"schemaExists":false,"authRequired":false,"secondFactorRequired":false,"hasExistingData":false,"syncVersion":39,"setupOperation":null}
isInitialized:false 表示尚未初始化。选择 New document 后界面会要求设置登录密码;设置完成即进入主界面(内置 577 条演示/帮助笔记,初始化日志实测 Table counts: notes: 577, revisions: 0, attachments: 19, branches: 592, attributes: 1411)。
⚠️ 初始化操作也可全部走接口完成,适合无人值守部署(以下命令均为实测):
# 1. 新建文档(首次调用返回 204,应用日志可见 "Setup operation 'new-document' finished") curl -s -X POST http://localhost:8139/api/setup/new-document # 2. 设置登录密码(表单字段 password1/password2,成功后 302 跳转) curl -i -X POST http://localhost:8139/set-password -d "password1=<你的密码>&password2=<你的密码>" # 实测回显:HTTP/1.1 302 Found … Location: login # 3. 登录(成功后 302 跳转并下发会话 Cookie) curl -i -c cookies.txt -X POST http://localhost:8139/login -d "password=<你的密码>" # 实测回显:HTTP/1.1 302 Found … Location: .⚠️ 已初始化后再次调用
POST /api/setup/new-document会被拒绝,实测回显:{"message":"App already initialized."}(HTTP 401)——这是正常防护,不是故障。
4.5 登录验证
浏览器访问 http://<服务器IP>:8139 输入密码进入主界面;或用上述 Cookie 复验:
curl -s -b cookies.txt -o /dev/null -w "GET / -> %{http_code}\n" http://localhost:8139/
GET / -> 200
五、数据持久化说明
Trilium 全部状态都在数据目录 /opt/trilium/data(容器内 /home/node/trilium-data),不含任何外部数据库,备份该目录即备份全部数据。初始化完成后的目录结构(实测):
backup/ # 备份产出目录(backup-<名称>.db)
config.ini # 服务配置(首次启动自动生成)
document.db # SQLite 主库:全部笔记/属性/附件元数据
document.db-wal # SQLite WAL 预写日志
document.db-shm # SQLite 共享内存文件
healthcheck-url # 健康检查端点说明文件
log/ # 运行日志
session_secret.txt
tmp/ # 临时文件
重建验证(真实实测):docker compose down 移除容器与网络但数据目录原样保留,docker compose up -d 重建后笔记原样可查:
docker compose down
Network trilium-01060-stack_trilium-net Removing
Network trilium-01060-stack_trilium-net Removed
docker compose up -d && sleep 8 && docker compose ps
Container trilium-0.106.0-app Started
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
trilium-0.106.0-app triliumnext/trilium:v0.106.0 "docker-entrypoint.s…" trilium 7 seconds ago Up 7 seconds (healthy) 0.0.0.0:8139->8080/tcp, [::]:8139->8080/tcp
💡 技术拓展:数据目录挂载方式不止 bind mount 一种,常见选项对比——
方式 特点 适用 bind mount(本方案) 路径直观、便于 rsync/快照备份 物理机/常规服务器 named volume Docker 统一管理,迁移需 docker volume操作纯容器化运维体系 网络存储挂载 可跨机漂移,但需注意文件锁 SMB 需加 nobrl,noperm(官方文档明确要求)本方案采用 bind mount:路径透明、备份直观,与官方 compose 默认行为一致。
六、环境变量表
实测验证过的环境变量(docker compose up -d 注入后实测确认):
| 环境变量 | 默认值 | 说明 |
|---|---|---|
TRILIUM_DATA_DIR | /home/node/trilium-data | 数据目录;必须与 volumes 容器侧路径一致 |
TRILIUM_PORT | 8080 | 服务监听端口;实测注入 TRILIUM_PORT=8090 后容器内改听 8090(/proc/net/tcp 出现 1F9A),原映射端口随即不通 |
USER_UID / USER_GID | 未设置时保持 1000 | 启动脚本 start-docker.sh 读取,用于重设容器内 node 用户的 uid/gid(实测未设置时输出 No USER_UID specified, leaving 1000) |
另有官方支持但本文未逐项实测的变量:TRILIUM_PROFILE(多 profile 数据目录)、TRILIUM_BACKUP_DIR、TRILIUM_LOG_DIR、TRILIUM_TMP_DIR、TRILIUM_CONFIG_INI_PATH(配置文件自定义路径)、TRILIUM_SAFE_MODE(安全模式)、TRILIUM_ENV、TRILIUM_RESOURCE_DIR(来源:官方镜像内程序对 TRILIUM_ 前缀环境变量的枚举,2026-10-22 查询)。rootless 变体另有 TRILIUM_UID/TRILIUM_GID/TRILIUM_VARIANT(来源:官方 docker-compose.rootless.yml)。
七、配置参数说明
首次启动会在数据目录生成 config.ini,其内容与官方 config-sample.ini 完全一致(逐行比对实测),即官方样例就是默认值。常用项速览(完整逐项解析见 《Trilium v0.106.0 配置参数详解》):
[Network] port=8080:config.ini 中的监听端口,与环境变量TRILIUM_PORT均可控制,后者优先级更高(实测见六);[General] noAuthentication=false:改为 true 可免密码访问,仅建议纯内网 + 防火墙封禁的场景;[Security] backendScriptingEnabled=false:后端脚本执行开关。实测改为 true 重启后,启动日志出现WARNING: Backend script execution is ENABLED. Backend scripts have full server access including filesystem, network, and OS commands. Only enable in trusted environments.;默认 false 时日志为Backend script execution is DISABLED. Set [Security] backendScriptingEnabled=true in config.ini to enable.。
修改 config.ini 后需 docker compose restart 生效(实测生效流程:编辑 → restart → 日志变化)。
八、配置文件挂载
config.ini 位于数据目录内,随 /opt/trilium/data bind mount 天然持久化,无需额外挂载条目;直接在宿主机编辑即可:
vi /opt/trilium/data/config.ini
docker compose restart trilium
⚠️ 首次启动前也可以在宿主机预放一份
config.ini(内容可从官方仓库assets/config-sample.ini获取),服务启动时直接采用;首次启动后 config.ini 已存在,编辑即可。⚠️ 不要把 config.ini 挂载成单独的只读文件:服务可能在运行期改写该文件(UI 设置项会落盘),单独挂载会引发写入失败。
九、等价 docker run
不使用 Compose 的等价命令(已在独立数据目录实测:容器 healthy、首启状态接口返回 isInitialized:false):
docker run -d \
--name trilium-app \
--restart unless-stopped \
-p 8139:8080 \
-v /opt/trilium/data:/home/node/trilium-data \
-e TRILIUM_DATA_DIR=/home/node/trilium-data \
triliumnext/trilium:v0.106.0
7a9567e66d46b2e23f08528aae2021b15ac1860f26174581a437163dbb3a4847
docker ps --filter name=trilium-app --format '{{.Names}} {{.Status}} {{.Ports}}'
trilium-0.106.0-runtest Up 8 seconds (healthy) 0.0.0.0:8136->8080/tcp, [::]:8136->8080/tcp
(该验证实例使用独立数据目录与 8136 端口,首启状态实测:)
curl -s http://localhost:8136/api/setup/status
{"isInitialized":false,"schemaExists":false,"authRequired":false,"secondFactorRequired":false,"hasExistingData":false,"syncVersion":39,"setupOperation":null}
生产环境仍建议用 Compose:配置即文件、升级回滚可追溯。
十、常用运维命令
以下命令均在部署目录 /opt/trilium/compose/ 下执行。
10.1 日常启停与状态
docker compose ps # 状态与健康(见 4.2 回显)
docker compose logs -f trilium # 跟踪日志(Ctrl+C 退出)
docker compose stop # 停止(保留容器)
docker compose start # 启动
docker compose restart trilium # 重启(改 config.ini 后使用)
docker compose down # 停止并移除容器/网络,数据目录不受影响(见五回显)
10.2 数据库备份
用 ETAPI 触发在线备份(实测 HTTP 204,产物为数据目录下 backup/backup-now.db):
curl -s -X PUT http://localhost:8139/etapi/backup/now -H "Authorization: <ETAPI token>" -w "HTTP %{http_code}\n"
HTTP 204
⚠️ 是 PUT 不是 POST:实测
POST /etapi/backup/now返回{"message":"Router not found for request POST /etapi/backup/now"}(HTTP 404)。备份名即文件名组成部分:backup-now.db。ETAPI 用法详见 《Trilium v0.106.0 常用 CLI 命令与工具详解》。
10.3 升级与回滚(已实测演练)
升级三步:改 tag → pull → up -d(Compose 自动重建容器,数据目录不动):
# 1. 编辑 docker-compose.yml 把 image: triliumnext/trilium:v0.106.0 改为目标版本(如 v0.107.0)
vi docker-compose.yml
# 2. 拉取新镜像
docker compose pull
Image triliumnext/trilium:latest Pulling
Image triliumnext/trilium:latest Pulled
# 3. 重建(实测输出)
docker compose up -d
Container trilium-0.106.0-app Starting
Container trilium-0.106.0-app Started
docker compose ps --format '{{.Name}} {{.Image}} {{.Status}}'
trilium-0.106.0-app triliumnext/trilium:latest Up 6 seconds (healthy)
回滚:把 tag 改回旧版本再 docker compose up -d 即可(实测回锚 v0.106.0 后 /api/health-check 返回 200)。若升级后数据异常,先 docker compose down,用 backup/ 中的 backup-<日期>.db 覆盖 document.db 再回锚启动。
⚠️ 官方 v0.106.0 Release Notes 特别提示:升级后若容器显示 unhealthy,先检查 compose 中是否自定义覆盖了
healthcheck(新版健康检查脚本为docker_healthcheck.sh,自定义覆盖会导致检查路径失效),必要时删除旧容器由 Compose 重建。⚠️ 跨大代际升级(zadam v0.63.x 时代 → TriliumNext)不可一步到位直接同步旧客户端,官方明确 sync 版本已递增;先升级服务器并按官方升级文档处理,再同步各客户端(见 《Trilium 介绍与选型指南》2.2 节溯源)。
十一、常见问题
Q1:curl 健康检查返回 000 / 连接被拒?
先看 docker compose ps 是否 healthy:若一直 starting,docker compose logs trilium 查看监听端口——若注入过 TRILIUM_PORT 而端口映射仍指向 8080 就会出现映射错位(实测:TRILIUM_PORT=8090 时宿主 8139 → 容器 8080 映射失效,curl 返回 000)。要么去掉该变量,要么把 ports: 同步改成 '8139:8090'。
Q2:POST /api/setup/new-document 返回 401 "App already initialized"?
应用已初始化过(数据目录里已有 document.db)。这是防护逻辑不是故障;如需重新初始化,备份后清空数据目录再 up -d。
Q3:修改 config.ini 后不生效?
config.ini 仅在启动时读取,修改后必须 docker compose restart trilium。确认改的是数据目录内生效文件(/opt/trilium/data/config.ini),不是部署目录里的 compose 文件。
Q4:docker compose down 会删数据吗?
不会。down 只移除容器与网络(见五回显),bind mount 的数据目录原样保留;但不要对数据目录执行 docker compose down -v 之外的清理脚本——-v 对 bind mount 同样无影响,真正危险的是手动 rm -rf /opt/trilium/data。
Q5:数据目录放 NAS/SMB 上可行吗?
可行但需挂载参数 nobrl 与 noperm(来源:官方 Docker 安装文档引用上游 issue #415,2026-10-22 查询),否则 SQLite 文件锁在 SMB 上会异常。
Q6:Compose 项目名怎么和写的不一样?
项目名中的点会被规范化:name: trilium-0.106.0-stack 实际生效为 trilium-01060-stack(down 回显可证)。想避免歧义就用不含点的名字,如 trilium-0-106-0-stack。
十二、参考链接
- 官方 Docker 安装文档:https://docs.triliumnotes.org/user-guide/setup/server/installation/docker
- 官方 docker-compose.yml(v0.106.0 标签):https://github.com/TriliumNext/Trilium/blob/v0.106.0/docker-compose.yml
- 官方 rootless compose:https://github.com/TriliumNext/Trilium/blob/v0.106.0/docker-compose.rootless.yml
- 官方镜像页:https://hub.docker.com/r/triliumnext/trilium/
- 官方升级文档:https://docs.triliumnotes.org/user-guide/setup/upgrading
- 本专栏相关篇目:《Trilium 介绍与选型指南》、《Trilium v0.106.0 配置参数详解》、《Trilium v0.106.0 常用 CLI 命令与工具详解》