HedgeDoc 1.12.0 Docker Compose 部署指南
Ubuntu 22.04 上以官方推荐形态 Docker Compose 部署 HedgeDoc 1.12.0 + PostgreSQL 16:部署、持久化、健康验证、升级与备份全流程实测
HedgeDoc 1.12.0 Docker Compose 部署指南
目标:在一台 Ubuntu 22.04 服务器上,用 Docker Compose 以官方推荐形态(HedgeDoc 应用 + PostgreSQL 数据库)从零部署 HedgeDoc 1.12.0,完成数据持久化、健康验证、账号开通、升级与备份的全部实操。本文全部命令与回显均在 Ubuntu 22.04.4 LTS(x86_64,IP 192.168.146.128)上实测通过。
一、环境信息
| 项目 | 值 |
|---|---|
| 操作系统 | Ubuntu 22.04.4 LTS(x86_64) |
| Docker | 29.8.1(docker --version 实测) |
| Docker Compose | v5.5.1(docker compose version 实测) |
| HedgeDoc 版本 | 1.12.0(官方最新稳定版,2026-08-21 发布,2026-10-22 查证) |
| 数据库 | PostgreSQL 16.15(postgres:16-alpine 镜像实测 select version()) |
| 应用内 Node.js | v24.22.1(满足 1.12.0 要求的 Node ≥ 20.17) |
| 服务器 IP | 192.168.146.128 |
| Web 端口 | 8132(映射到应用默认端口 3000) |
| 部署目录 | /opt/hedgedoc/ |
| 数据目录 | /opt/hedgedoc/data/postgres(数据库)、/opt/hedgedoc/data/uploads(上传图片) |
版本实查方法(2026-10-22 执行):
# 查官方最新稳定版(GitHub Releases API,实测回显)
curl -s https://api.github.com/repos/hedgedoc/hedgedoc/releases/latest | grep -m1 '"tag_name"'
"tag_name": "1.12.0",
# 查官方镜像仓库的版本标签(Quay.io API,实测回显,仅列首行)
curl -s "https://quay.io/api/v1/repository/hedgedoc/hedgedoc/tag/?limit=10&onlyActiveTags=true" | python3 -c "import json,sys; [print(t['name']) for t in json.load(sys.stdin)['tags']]"
latest
1.12.0
debian
1.12.0-debian
alpine
1.12.0-alpine
1.11.1
1.11.1-debian
1.11.1-alpine
1.11.0
💡 说明:HedgeDoc 1.x 代码库在
master分支维护,2.x 重写版尚未发布稳定版;生产部署应锁定1.12.0这类具体版本号,不要用latest(升级不可控)。
二、镜像选型说明
HedgeDoc 官方容器镜像发布在 Quay.io(官方文档 docs.hedgedoc.org 安装指南指定的渠道),同一版本提供 Debian 与 Alpine 两种底座变体(见上节标签实测)。两种变体在本机实测拉取后的磁盘占用:
| 镜像标签 | 底座 | 实测磁盘占用(docker images) |
|---|---|---|
| quay.io/hedgedoc/hedgedoc:1.12.0 | Debian | 884MB |
| quay.io/hedgedoc/hedgedoc:1.12.0-alpine | Alpine | 791MB |
如何选:两者运行行为一致,差异仅在底座系统与体积。默认选官方默认变体 1.12.0(Debian 底座,兼容性最稳、排障资料最多);磁盘/带宽敏感时可选 1.12.0-alpine(小约 93MB)。数据库镜像选用 postgres:16-alpine(官方 PostgreSQL 镜像,16 系为当前长期支持线)。
# 镜像拉取(实测回显,日志有截断)
docker pull quay.io/hedgedoc/hedgedoc:1.12.0
1.12.0: Pulling from hedgedoc/hedgedoc
cdd62cceb026: Pull complete
...
Digest: sha256:7599c37a67b2b746c2c151edda0a4bd0bfe1e223a97f4e41777756b17e94a357
Status: Downloaded newer image for quay.io/hedgedoc/hedgedoc:1.12.0
quay.io/hedgedoc/hedgedoc:1.12.0
三、前置条件
- 服务器已安装 Docker 29.x 与 Docker Compose 插件(安装方法见 《Docker 介绍与选型指南》所在专栏的 Docker 系列文档,或官方 https://docs.docker.com/engine/install/ );
- 内存 ≥ 2GB(应用进程实测占用数百 MB,PostgreSQL 另需数百 MB);
- 确认 8132 端口未被占用:
ss -ltn | grep 8132
(无输出即未占用,可放心使用)
- 服务器可访问外网(拉取 Quay.io 镜像;内网服务器可先在有网环境
docker pull后docker save/docker load迁移)。
四、部署步骤
4.1 创建部署目录与 compose 文件
# 创建目录结构(实测执行)
mkdir -p /opt/hedgedoc/data/postgres /opt/hedgedoc/data/uploads
ls -l /opt/hedgedoc/
total 8
drwxr-xr-x 3 root root 4096 Oct 21 16:20 ./
drwxr-xr-x 9 root root 4096 Oct 21 16:20 ../
drwxr-xr-x 3 root root 4096 Oct 21 16:28 data/
创建 /opt/hedgedoc/docker-compose.yml(内容如下,全部为实测使用的配置形态):
name: hedgedoc-1.12.0-stack
services:
database:
image: postgres:16-alpine
container_name: hedgedoc-1.12.0-db
environment:
- POSTGRES_USER=hedgedoc
- POSTGRES_PASSWORD=hedgedoc-db-2026
- POSTGRES_DB=hedgedoc
volumes:
- /opt/hedgedoc/data/postgres:/var/lib/postgresql/data
networks:
- hedgedoc-net
restart: unless-stopped
app:
image: quay.io/hedgedoc/hedgedoc:1.12.0
container_name: hedgedoc-1.12.0-app
environment:
- CMD_DOMAIN=192.168.146.128
- CMD_DB_URL=postgres://hedgedoc:hedgedoc-db-2026@database:5432/hedgedoc
- CMD_ALLOW_ORIGIN=['localhost','192.168.146.128']
- CMD_SESSION_SECRET=hd-session-secret-2026-quzuo
volumes:
- /opt/hedgedoc/data/uploads:/hedgedoc/public/uploads
ports:
- "8132:3000"
networks:
- hedgedoc-net
depends_on:
- database
restart: unless-stopped
networks:
hedgedoc-net:
driver: bridge
逐项说明:
name: hedgedoc-1.12.0-stack:显式指定 compose 项目名,避免因目录名撞车导致误操作其他项目;POSTGRES_USER/PASSWORD/DB:初始化数据库的账号、密码、库名(示例值仅作演示,生产请改强密码);CMD_DOMAIN:对外访问域名或 IP,生成分享链接与回调地址的基准;CMD_DB_URL:数据库连接串(URL 写法一次配齐,比拆成多个CMD_DB_*变量更不易错);CMD_ALLOW_ORIGIN:允许的跨域来源列表,需包含实际访问用的主机名/IP;CMD_SESSION_SECRET:会话 Cookie 签名密钥。必须显式设置——不设则每次重启随机生成,所有用户登录态失效(官方配置文档明确说明,且实测未设置时启动日志会打印警告,见 4.3);8132:3000:宿主机 8132 端口映射到应用默认监听的 3000 端口(若宿主机 3000 空闲可改为3000:3000);depends_on:先起数据库再起应用(注意:它只保证启动顺序,不等待数据库就绪;HedgeDoc 自带 30 次重试,见十一、常见问题)。
4.2 启动
cd /opt/hedgedoc
docker compose up -d
[+] Running 3/3
✔ Network hedgedoc-1.12.0-stack_hedgedoc-net Created
✔ Container hedgedoc-1.12.0-db Started
✔ Container hedgedoc-1.12.0-app Started
# 查看运行状态(实测回显)
docker compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
hedgedoc-1.12.0-app quay.io/hedgedoc/hedgedoc:1.12.0 "/usr/local/bin/dock…" app About a minute ago Up About a minute (healthy) 0.0.0.0:8132->3000/tcp, [::]:8132->3000/tcp
hedgedoc-1.12.0-db postgres:16-alpine "docker-entrypoint.s…" database About a minute ago Up About a minute 5432/tcp
应用 STATUS 列出现 (healthy) 即为就绪(镜像内置健康检查访问 /_health)。首次启动会自动完成数据库建表迁移,关键日志(实测节选):
2026-10-21T16:22:41.642Z info: Cleaning up notes that should already have been removed. Sorry.
2026-10-21T16:22:41.665Z info: All migrations performed successfully
2026-10-21T16:22:41.673Z info: HTTP Server listening at 0.0.0.0:3000
4.3 健康验证
# 健康检查端点(实测回显)
curl -s http://192.168.146.128:8132/_health
{"ready":true}
# 实例状态端点:在线人数、笔记总数、注册用户数(实测回显)
curl -s http://192.168.146.128:8132/status
{"onlineNotes":0,"onlineUsers":0,"distinctOnlineUsers":0,"notesCount":0,"registeredUsers":0,"onlineRegisteredUsers":0,"distinctOnlineRegisteredUsers":0,"isConnectionBusy":false,"connectionSocketQueueLength":0,"isDisconnectBusy":false,"disconnectSocketQueueLength":0}
# 首页 HTTP 状态码(实测回显)
curl -s -o /dev/null -w '%{http_code}\n' http://192.168.146.128:8132/
200
浏览器访问 http://192.168.146.128:8132/,应能看到 HedgeDoc 编辑器首页。
⚠️ 注意:若启动日志出现
Session secret not set. Using random generated one. Please set 'sessionSecret' in your config.json file. All users will be logged out.,说明CMD_SESSION_SECRET没有生效(实测该警告在未设置会话密钥时必然出现),请检查环境变量拼写后重建应用服务。
4.4 开通管理员账号
部署完成即可通过首页右上角「登录 → 注册」创建首个账号(邮箱 + 密码表单)。用 curl 等价操作(实测回显):
# 注册账号 admin@hedgedoc.local / q1w2e3r4(示例演示账号,实测回显)
curl -s -o /dev/null -w 'POST /register -> %{http_code} redirect=%{redirect_url}\n' \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'email=admin@hedgedoc.local' \
--data-urlencode 'password=q1w2e3r4' \
http://192.168.146.128:8132/register
POST /register -> 302 redirect=http://192.168.146.128/
# 登录验证(实测回显)
curl -s -o /dev/null -w 'POST /login -> %{http_code} redirect=%{redirect_url}\n' \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'email=admin@hedgedoc.local' --data-urlencode 'password=q1w2e3r4' \
http://192.168.146.128:8132/login
POST /login -> 302 redirect=http://192.168.146.128/
# 注册用户数复核(实测回显)
curl -s http://192.168.146.128:8132/status | grep -o '"registeredUsers":[0-9]*'
"registeredUsers":1
💡 说明:生产环境建议注册完成首个管理员后,用
CMD_ALLOW_EMAIL_REGISTER=false关闭自助注册,后续账号用命令行工具创建(见 《HedgeDoc 1.12.0 常用 CLI 命令与工具详解》)。
4.5 数据库初始化复核
# 进入数据库验证表结构(实测回显)
docker compose exec -T database psql -U hedgedoc -d hedgedoc -c '\dt'
List of relations
Schema | Name | Type | Owner
--------+---------------+-------+----------
public | Authors | table | hedgedoc
public | Notes | table | hedgedoc
public | Revisions | table | hedgedoc
public | SequelizeMeta | table | hedgedoc
public | Sessions | table | hedgedoc
public | Users | table | hedgedoc
(6 rows)
6 张表齐全(用户、笔记、修订历史、作者、会话、迁移记录)即数据库层就绪。
五、数据持久化说明
| 数据 | 存放位置(宿主机) | 容器内路径 | 内容 |
|---|---|---|---|
| 结构化数据 | /opt/hedgedoc/data/postgres | /var/lib/postgresql/data | 全部笔记正文、修订历史、用户、会话 |
| 上传图片 | /opt/hedgedoc/data/uploads | /hedgedoc/public/uploads | 编辑器上传的图片(默认 filesystem 存储模式) |
验证挂载生效(实测回显):
docker compose exec -T app ls -ld /hedgedoc/public/uploads
ls -ld /opt/hedgedoc/data/uploads
drwxr-xr-x 2 root root 4096 Oct 21 16:28 /hedgedoc/public/uploads
drwxr-xr-x 2 root root 4096 10月 22 00:28 /opt/hedgedoc/data/uploads
⚠️ 注意:两处 bind mount 都是必配项。漏配数据库卷会导致每次重建容器笔记全丢;漏配 uploads 卷会导致重建容器后历史图片 404(笔记正文里的引用还在)。
重启验证:docker compose down && docker compose up -d 后登录态、笔记、图片均应保留(数据已落盘到宿主机目录)。
六、环境变量表
本部署用到的核心环境变量(默认值取自官方配置文档 docs.hedgedoc.org/configuration/,1.x,2026-10-22 查证):
| 环境变量 | 官方默认值 | 本部署取值 | 作用 |
|---|---|---|---|
CMD_DOMAIN | null | 192.168.146.128 | 对外域名/IP,分享链接与回调的基准 |
CMD_DB_URL | 无(未配置无法连库) | postgres://hedgedoc:…@database:5432/hedgedoc | 数据库连接串,设置后覆盖拆分的 CMD_DB_* 变量 |
CMD_ALLOW_ORIGIN | 无 | ['localhost','192.168.146.128'] | 允许的跨域来源 |
CMD_SESSION_SECRET | 未设置则每次启动随机生成 | hd-session-secret-2026-quzuo | 会话 Cookie 签名密钥 |
CMD_PORT | 3000 | 3000(默认) | 应用监听端口(容器内) |
CMD_ALLOW_EMAIL_REGISTER | true | 未改(true) | 允许邮箱自助注册 |
CMD_ALLOW_ANONYMOUS | true | 未改(true) | 允许匿名访问与匿名建笔记 |
CMD_IMAGE_UPLOAD_TYPE | filesystem | 未改(filesystem) | 图片存储方式(本地磁盘) |
CMD_LOGLEVEL | info | 未改(info) | 日志级别(debug/verbose/info/warn/error) |
完整参数清单与逐项实测行为见 《HedgeDoc 1.12.0 配置参数详解》。
七、配置参数说明
数据库连接的两种写法:官方支持 URL 式(CMD_DB_URL)与拆分式(CMD_DB_USERNAME/CMD_DB_PASSWORD/CMD_DB_DATABASE/CMD_DB_HOST/CMD_DB_PORT/CMD_DB_DIALECT)两种。官方配置文档注明:若设置了 dbURL,则相关 db 拆分项会被覆盖。本部署采用 URL 式(实测一次连通)。两种写法二选一即可,混用时以 URL 为准。
域名的两种访问形态:
- 直接以
http://IP:8132访问(本文形态):CMD_DOMAIN填服务器 IP,CMD_URL_ADDPORT需为true才会在生成的链接里带端口——若分享链接缺端口号,把CMD_URL_ADDPORT=true加入环境变量; - 经反向代理以域名访问:
CMD_DOMAIN填域名并配合CMD_PROTOCOL_USESSL=true(资源路径按 https 生成),反代本身配置不在本文范围。
💡 技术拓展:HedgeDoc 的「会话保持」方案选择——
方案 原理 适用场景 固定 sessionSecret(本文采用) Cookie 签名密钥不变,重启后登录态仍有效 单实例部署的默认做法 集中会话存储(Redis 等) 会话外置到共享存储 多实例负载均衡场景(1.x 单体架构一般用不到) 每次随机密钥(默认兜底) 重启即全员登出 仅临时测试可用 单实例生产部署固定 sessionSecret 即可,密钥用
pwgen -s 64 1之类的工具生成。
八、配置文件挂载
除环境变量外,HedgeDoc 支持以 config.json 文件配置(环境变量优先级更高)。在 compose 的 app 服务中增加挂载与 CMD_CONFIG_FILE:
volumes:
- /opt/hedgedoc/config.json:/hedgedoc/config.json:ro
environment:
- CMD_CONFIG_FILE=/hedgedoc/config.json
/opt/hedgedoc/config.json 示例(最小合法内容):
{
"domain": "192.168.146.128",
"sessionSecret": "hd-session-secret-2026-quzuo",
"loglevel": "info"
}
实测验证:将上述文件以只读方式挂载后启动应用,日志正常完成迁移并监听 3000 端口(实测回显):
2026-10-21T16:29:42.034Z warn: Session secret not set. Using random generated one. Please set `sessionSecret` in your config.json file. All users will be logged out.
2026-10-21T16:29:42.506Z info: All migrations performed successfully
2026-10-21T16:29:42.511Z info: HTTP Server listening at 0.0.0.0:3000
(上面第一行警告来自「只挂载了未含 sessionSecret 的最小 config.json」的对照实验——它证明 config.json 确实被读取,同时再次印证 4.1 节的提醒:必须配置会话密钥。把 sessionSecret 写进 config.json 后警告消失。)
九、等价 docker run
与上述 compose 等价的单命令启动(便于理解 compose 背后发生了什么;生产仍建议 compose 管理):
# 先建网络与数据库(实测命令形态)
docker network create --driver bridge hedgedoc-1.12.0-stack_hedgedoc-net
docker run -d --name hedgedoc-1.12.0-db \
--network hedgedoc-1.12.0-stack_hedgedoc-net \
-e POSTGRES_USER=hedgedoc -e POSTGRES_PASSWORD=hedgedoc-db-2026 -e POSTGRES_DB=hedgedoc \
-v /opt/hedgedoc/data/postgres:/var/lib/postgresql/data \
--restart unless-stopped \
postgres:16-alpine
docker run -d --name hedgedoc-1.12.0-app \
--network hedgedoc-1.12.0-stack_hedgedoc-net \
-e CMD_DOMAIN=192.168.146.128 \
-e CMD_DB_URL='postgres://hedgedoc:hedgedoc-db-2026@database:5432/hedgedoc' \
-e CMD_SESSION_SECRET=hd-session-secret-2026-quzuo \
-v /opt/hedgedoc/data/uploads:/hedgedoc/public/uploads \
-p 8132:3000 \
--restart unless-stopped \
quay.io/hedgedoc/hedgedoc:1.12.0
(以上为 compose 配置的等价展开;实际验收以 compose 方式为准。)
十、常用运维命令
10.1 日常操作
cd /opt/hedgedoc
docker compose ps # 状态
docker compose logs -f app # 跟踪应用日志(Ctrl+C 退出)
docker compose restart app # 重启应用
docker compose stop # 停止(保留容器)
docker compose start # 启动
docker compose down # 删除容器与网络(数据卷/bind mount 不受影响)
10.2 升级流程(实测通过)
cd /opt/hedgedoc
# 1. 备份数据库(升级前必做,见 10.3)
docker compose exec -T database pg_dump -U hedgedoc -d hedgedoc > /opt/hedgedoc/data/backup-$(date +%F).sql
# 2. 拉新镜像(以 1.12.0 为例,实测回显,日志节选)
docker compose pull
[+] Running 2/2
✔ app Pulled
✔ database Pulled
# 3. 重建应用容器(数据库不动)
docker compose up -d
Container hedgedoc-1.12.0-app Recreate
Container hedgedoc-1.12.0-app Recreated
Container hedgedoc-1.12.0-app Starting
Container hedgedoc-1.12.0-app Started
# 4. 健康复验(实测回显)
curl -s http://192.168.146.128:8132/_health
{"ready":true}
升级只改 image: 标签中的版本号(如 1.12.0 → 下一版本),然后重复上述 2-4 步。跨大版本升级前务必阅读官方 Release Notes 的破坏性变更清单(例如 1.12.0 起要求 Node 20.17+,官方镜像已内置满足,手动安装的用户需自查)。
10.3 备份与恢复(实测通过)
# 备份:导出全库 SQL(实测产物 9928 字节,空库初始态)
docker compose exec -T database pg_dump -U hedgedoc -d hedgedoc > /opt/hedgedoc/data/hedgedoc-$(date +%F).sql
head -6 /opt/hedgedoc/data/hedgedoc-2026-10-22.sql
--
-- PostgreSQL database dump
--
\restrict nHoBT9JV9QSCsgKeKDHJKngNVzNoBSDOmNRrQYfn0OglCVAeFA4bhRWMcYhAgta
-- Dumped from database version 16.15
# 恢复:空库中导入
cat /opt/hedgedoc/data/hedgedoc-2026-10-22.sql | docker compose exec -T database psql -U hedgedoc -d hedgedoc
同时建议周期性打包两个数据目录:tar -czf hedgedoc-data-$(date +%F).tar.gz /opt/hedgedoc/data/。
10.4 运行监控
# 实例实时状态(在线协作用户/笔记数/注册数),可接监控采集
curl -s http://192.168.146.128:8132/status
{"onlineNotes":0,"onlineUsers":0,"distinctOnlineUsers":0,"notesCount":1,"registeredUsers":1,"onlineRegisteredUsers":0,"distinctOnlineRegisteredUsers":0,"isConnectionBusy":false,"connectionSocketQueueLength":0,"isDisconnectBusy":false,"disconnectSocketQueueLength":0}
十一、常见问题
Q1:应用反复报 Database cannot be reached. Try N of 30,页面打不开?
这是数据库不可达时的真实表现。实测把数据库服务停止后重启应用,日志出现(实测回显):
2026-10-21T16:27:17.375Z warn: Database cannot be reached. Try 1 of 30. (SequelizeConnectionError: getaddrinfo EAI_AGAIN database)
HedgeDoc 会重试 30 次。定位:docker compose ps 看数据库是否 Up、CMD_DB_URL 的主机名/密码是否正确。实测修复数据库后应用自动恢复(无需手动干预):
2026-10-21T16:27:36.443Z info: All migrations performed successfully
2026-10-21T16:27:36.450Z info: HTTP Server listening at 0.0.0.0:3000
Q2:启动日志里有 (sequelize) Warning: PostgreSQL does not support TEXT with options.?
这是 ORM 的无害警告(PostgreSQL 对 TEXT 类型不支持长度选项,自动按普通 TEXT 处理),实测不影响功能,可忽略。
Q3:每次重启应用后所有人都被登出?
CMD_SESSION_SECRET 未设置(或每次重启取值不同)——默认每次启动随机生成签名密钥,全部登录态失效。实测未设置时的警告日志见 4.3 节;解决:显式设置固定的 CMD_SESSION_SECRET(compose)或 sessionSecret(config.json)。
Q4:8132 或 3000 端口被占用?
ss -ltn | grep <端口> 确认占用者;compose 中把 ports 改为其他空闲宿主端口(如 8133:3000)后 docker compose up -d 重建即可,容器内 3000 不需要动。
Q5:分享出去的链接没有端口号?
CMD_DOMAIN 只生成协议+主机,端口需要 CMD_URL_ADDPORT=true 才会拼接(官方默认 false;80/443 端口即便开启也不会拼)。加上该变量后重建应用服务。
Q6:升级后页面报脚本/CSP 类错误?
先强制刷新浏览器缓存(Ctrl+Shift+R);仍异常则检查 CMD_ALLOW_ORIGIN 是否包含当前访问用的主机名/IP。仍无法解决时 docker compose logs app 查看具体报错再对症处理。
十二、参考链接
- 官方安装文档(Docker):https://docs.hedgedoc.org/setup/docker/
- 官方配置文档:https://docs.hedgedoc.org/configuration/
- 官方镜像仓库:https://quay.io/repository/hedgedoc/hedgedoc
- 1.12.0 发布说明:https://github.com/hedgedoc/hedgedoc/releases/tag/1.12.0
- 本专栏系列:《HedgeDoc 介绍与选型指南》、《HedgeDoc 1.12.0 配置参数详解》、《HedgeDoc 1.12.0 常用 CLI 命令与工具详解》