Jotty 1.29.2 Docker Compose 部署指南

基于 1.29.2 实测:目录准备、Docker Compose 部署文件、首次初始化、部署后验证、升级操作与五则排障实录。

JottyDocker Compose自托管Docker2026/10/30

Jotty 1.29.2 Docker Compose 部署指南

目标:在真实 Linux 服务器上以官方主推的 Docker Compose 形态交付 Jotty 1.29.2,覆盖目录准备、部署文件编写、首次初始化、部署后验证、升级与排障。本文所有命令与回显均来自本机实测(2026-10-30),组件背景与选型结论见《Jotty 1.29.2 介绍与选型指南》。

一、部署前准备

1.1 环境信息(实测)

项目实测值
操作系统Linux(内核 6.x,Docker Compose v2)
实测版本ghcr.io/fccview/jotty:1.29.2(官方 ghcr.io 发布物,2026-10-25 构建)
服务内部端口3000(Node.js 24 运行时监听)
宿主端口(本例)8131(部署前用 ss -ltn 确认未被占用)
数据目录./data、./config、./cache(bind 挂载)
运行身份1000:1000

版本号取证依据:GitHub releases.atom 最新稳定 entry 为 "Stable 1.29.2"(2026-10-25),与官方交付物 1.29.2 标签一致;该版本号同时会在部署后的 OpenAPI 文档接口中回显(见 3.3 节实测)。

1.2 选取空闲端口与网段(实测)

宿主端口避开已占用者,本例选定 8131;若宿主机上已有大量自定义 bridge 网络占用默认网段,需为 compose 网络显式指定空闲子网。实测检查方式:

ss -ltn
# 实测回显(节选):
# LISTEN 0 128 0.0.0.0:8128 ...
# LISTEN 0 128 0.0.0.0:8130 ...
# LISTEN 0 128 0.0.0.0:8155 ...

8128/8130/8155 等已被占用,8131 空闲,故映射 8131:3000。网段占用检查(实测回显):

docker network inspect $(docker network ls -q) | grep -oE '"Subnet": "[^"]+"' | sort -u
# 实测回显:
# "Subnet": "10.89.59.0/24"
# "Subnet": "10.89.60.0/24"
# "Subnet": "10.89.61.0/24"
# "Subnet": "172.17.0.0/16"

据此本例显式选用空闲的 10.89.56.0/24。

1.3 目录准备(官方步骤 + 实测)

官方 README"Getting Started"要求先建目录并赋属主 1000:1000(user: "1000:1000" 运行身份需要写权限):

mkdir -p config data/users data/checklists data/notes data/sharing data/encryption cache
chown -R 1000:1000 data/ config/ cache/

说明:cache 目录为可选项(官方 README 注明不挂载该路径则放弃缓存持久化,功能不受影响)。

二、编写部署文件并启动

2.1 docker-compose.yml(实测可用版本)

基于官方 docker-compose.yml(仓库 main 分支,查询日期 2026-10-30)调整端口与网络后,本例实际使用的文件如下:

name: jotty-1-29-2-stack

services:
  jotty:
    image: ghcr.io/fccview/jotty:1.29.2
    user: "1000:1000"
    ports:
      - "8131:3000"
    volumes:
      - ./data:/app/data:rw
      - ./config:/app/config:rw
      - ./cache:/app/.next/cache:rw
    restart: unless-stopped
    networks:
      - jotty-net
    environment:
      - NODE_ENV=production

networks:
  jotty-net:
    name: jotty-1-29-2-stack_jotty-net
    driver: bridge
    ipam:
      config:
        - subnet: 10.89.56.0/24

两处与官方示例的差异说明:

  • 标签用具体版本号而非 latest:与 releases.atom 的稳定版对齐,升级节奏自主可控;官方默认示例为 ghcr.io/fccview/jotty:latest,两者均可。
  • name: 与网络 subnet: 显式化:compose 项目名避免与既有部署冲突;子网按 1.2 节实测结果避开已占用网段。

注意 compose 项目名的规范化:name: 中若含点号(如 jotty-1.29.2-stack),Compose 会将其规范化为短横线(实测生成项目名 jotty-1-29-2-stack),后续 docker compose down 等操作要使用规范化后的名称。

2.2 启动(实测)

docker compose up -d
# 实测回显:
#  Network jotty-1-29-2-stack_jotty-net Created
#  Container jotty Creating
#  Container jotty Created
#  Container jotty Starting
#  Container jotty Started

状态确认:

docker compose ps
# 实测回显:
# NAME      IMAGE                          STATUS         PORTS
# jotty    ghcr.io/fccview/jotty:1.29.2   Up 12 seconds   0.0.0.0:8131->3000/tcp, [::]:8131->3000/tcp

启动日志(实测节选):

[patch:patches] freebsd_20260427: skipped (JOTTY_FREEBSD not set)
✓ Running next.config took 0.8ms
   jjjj               .       .
> Ready on http://0.0.0.0:3000

Ready on http://0.0.0.0:3000 即服务就绪标志。日志中的 patch:patches 行是官方入口脚本的运行时补丁器输出(依据 howto/DOCKER.md"Runtime Patches"章节:按环境变量按需打补丁,未设置 JOTTY_FREEBSD 时跳过 FreeBSD 兼容补丁,属正常现象)。

三、首次初始化与部署后验证

3.1 初始化管理员(官方流程)

官方 README"Initial Setup":首次访问时,SSO 未启用的实例会被引导至 /auth/setup 创建管理员,第一个注册用户自动成为管理员(isAdmin/isSuperAdmin)。实测从 /auth/setup 页面提取到表单字段:username、password、confirmPassword,提交即完成初始化。

实测对初始化入口的可达性验证:

curl -s -o /dev/null -w "GET / -> %{http_code} redirect=%{redirect_url}\n" http://127.0.0.1:8131/
# 实测回显:GET / -> 307 redirect=http://127.0.0.1:8131/auth/login
curl -s -o /dev/null -w "GET /auth/setup -> %{http_code}\n" http://127.0.0.1:8131/auth/setup
# 实测回显:GET /auth/setup -> 200

即:未初始化状态下访问首页会被 307 重定向至登录入口,初始化表单页直接返回 200。配置 SSO 的实例则跳过本地初始化、走 OIDC 登录(官方 README;SSO 环境变量见《Jotty 1.29.2 配置参数详解》)。

3.2 服务健康与鉴权开关验证(实测)

curl -s -o /dev/null -w "HTTP %{http_code}\n" http://127.0.0.1:8131/api/notes
# 实测回显:HTTP 401

未认证访问 API 返回 401,说明鉴权链路已生效;认证后的调用方式与密钥签发见《Jotty 1.29.2 REST API 实战指南》。

3.3 版本一致性核验(实测)

curl -s -H "x-api-key: <你的密钥>" http://127.0.0.1:8131/api/openapi.json | python3 -c "import json,sys; d=json.load(sys.stdin); print(d['info']['title'], d['info']['version'], 'paths:', len(d['paths']))"
# 实测回显:Jotty API 1.29.2 paths: 62

OpenAPI 文档回显 Jotty API 1.29.2,与所部署发布物标签一致,版本核对闭环。

3.4 资源占用(实测)

docker stats --no-stream --format "table {{.Name}}\t{{.MemUsage}}\t{{.CPUPerc}}"
# 实测回显(节选):
# NAME    MEM USAGE / LIMIT     CPU %
# jotty   189MiB / 15.07GiB     0.00%

空闲态常驻内存约 189MiB,符合轻量组件预期,1 核 1GB 规格的实例即可承载个人使用(实测口径:单用户、空数据)。

四、数据落盘形态(实测)

部署后所有业务数据以纯文件形态存在于 data/ 挂载目录,实测结构如下:

data/
├── checklists/admin/Uncategorized/S9 验收清单.md
├── notes/admin/Uncategorized/S9 验收笔记.md
├── users/users.json、sessions.json
├── sharing/、encryption/

要点:笔记与清单按 data/<类型>/<用户名>/<分类>/<标题>.md 归档,备份策略直接对 data/ 目录做整体快照即可;users.json 内含账户与 API 密钥,注意备份介质的访问控制。

五、升级操作

官方版本策略为 [STABLE].[FEATURE].[FIX](README,详见选型指南第四节)。升级标准动作:

  1. 备份 data/ 目录(官方在 Feature 版本发布说明中反复强调,迁移脚本在首次启动时自动执行);
  2. 修改 compose 中标签为最新稳定版本号(对照 releases.atom);
  3. docker compose pull && docker compose up -d(Compose v2 会按新标签重建服务实例,数据目录不变)。

六、排障实录(实测沉淀)

6.1 ghcr.io 拉取失败与代理白名单问题

国内网络环境下直连 ghcr.io 可能超时。实测尝试 DaoCloud 公共加速(ghcr.m.daocloud.io)被拒:

Error response from daemon: error from registry: 🚫 👀-> https://github.com/DaoCloud/public-image-mirror/issues/2328 🔗 这镜像不在白名单. this image is not in the allowlist.

结论:该加速源按白名单放行,fccview/jotty 不在列;实测本环境直连 ghcr.io 拉取 1.29.2 成功(约 400MB 层量)。若所在网络必须走加速,可自建 registry 代理或离线导入。

6.2 服务启动后无法写入数据目录

现象:初始化提交报错、日志出现写文件失败。根因:compose 声明 user: "1000:1000",而宿主 data/config 目录属主为 root。修复:按 1.3 节执行 chown -R 1000:1000。官方入口脚本仅在以 root 启动且设置了 PUID/PGID 时才自动调整属主;显式 user: 指令优先级更高(howto/ENV-VARIABLES.md 对 PUID/PGID 的说明),属主必须自行对齐。

6.3 自定义网络网段冲突

现象:docker compose up -d 报网络创建失败(与宿主既有 bridge 网段重叠)。修复:按 1.2 节实查空闲网段后在 compose 中显式 ipam.config.subnet。本例实测指定 10.89.56.0/24 后一次创建成功。

6.4 compose 项目名点号规范化

现象:name: jotty-1.29.2-stack 实际生成项目名 jotty-1-29-2-stack(点号规范化为短横线,实测回显见 2.2 节 Network 名称)。影响:docker compose -p 指定旧名会找不到项目;down/v 清理时统一使用规范化名。

6.5 缓存目录未挂载导致升级后首访变慢

官方 README 注明 ./cache:/app/.next/cache:rw 为可选持久化。省略该挂载时功能正常,但每次重建服务实例后运行时缓存需冷启动重建,首页首访耗时上升。个人实例建议保留该挂载。

七、交付清单核对

  • 目录属主 1000:1000(data/config/cache)
  • compose 显式 name: 与空闲 subnet:,标签锁定 1.29.2
  • 启动日志出现 Ready on http://0.0.0.0:3000
  • /auth/setup 可达(200),未认证 API 返回 401
  • OpenAPI 回显版本 1.29.2
  • 空闲内存占用约 189MiB
  • data/ 目录已纳入备份范围

参数层面的进一步调优(SSO、上传上限、公开附件开关等)见《Jotty 1.29.2 配置参数详解》。