团队文档这件事,Confluence 太重、语雀要钱、Notion 在国内访问不稳。Docmost 是这两年冒出来的一个开源选项,定位很明确:开源版的协作文档与知识库。
一、项目介绍
官方 README 的一句话定义:Open-source collaborative wiki and documentation software。
它不是「把 Markdown 存进数据库」那种简陋方案。Docmost 的核心卖点是实时协作——多个人同时编辑同一篇文档,光标和改动实时同步,这是需要 CRDT 或者 OT 算法支撑的能力,也是它和一堆静态 Wiki 工具拉开差距的地方。
技术上:前端 React,后端 NestJS,数据库 PostgreSQL,缓存与实时通信走 Redis。所以官方 compose 里是三个容器,一个都不能少。
仓库 2.2 万 star,主体 AGPL-3.0,最近提交 2026 年 11 月 1 日。
二、功能拆解
官方列出的能力清单:
- 实时协作(Real-time collaboration):多人同时编辑,改动即时可见
- 图表(Diagrams):内嵌 Draw.io、Excalidraw、Mermaid 三种。前两个是画图工具,Mermaid 是写代码出图(流程图、时序图、甘特图)
- 空间(Spaces):文档按空间划分,类似 Confluence 的 Space,不同团队一个空间
- 权限管理(Permissions management):按空间、按页面控制谁能看谁能改
- 用户组(Groups):批量授权,不用一个个加人
- 评论(Comments):页内讨论
- 页面历史(Page history):版本回溯,改错了能找回来
- 搜索(Search):全文检索
- 附件(File attachments):图片、文件直接拖进去
- 嵌入(Embeds):Airtable、Loom、Miro 等第三方内容
- 多语言(Translations):10 种以上界面语言,含简体中文
一句话取舍:它瞄准的是「Notion 的文档部分」。Notion 的数据库视图、看板、公式这些高级玩法它没有;但如果你只需要一个能多人协作、有权限体系、能画图的知识库,它比 Notion 更适合放在内网。
三、官方链接
- GitHub 仓库:https://github.com/docmost/docmost
- 官网:https://docmost.com
- 官方文档:https://docmost.com/docs
- 安装文档:https://docmost.com/docs/installation
- 官方 compose 文件:https://raw.githubusercontent.com/docmost/docmost/main/docker-compose.yml
- 云版本(不想自建):https://docmost.com/pricing
- X / Twitter:https://twitter.com/DocmostHQ
四、环境要求
| 项目 | 要求 |
|---|---|
| 系统 | Linux(官方文档以 Ubuntu 为例) |
| Docker | 需要,官方文档第一步就是装 Docker |
| Docker Compose | v2(docker compose 子命令) |
| 数据库 | PostgreSQL 18(compose 内置) |
| 缓存 | Redis 8(compose 内置) |
| 端口 | 3000 |
| 内存 | 2GB 起步比较稳(三个容器 + Node 应用) |
| 磁盘 | 10GB 起步,附件会持续增长 |
几个需要提前想清楚的点:
- 必须配 HTTPS。Docmost 没有强制,但实时协作走 WebSocket,HTTPS 环境下最稳,而且 Cookie 的安全属性在 HTTP 下会打折
APP_SECRET必须改。官方 compose 里写的是REPLACE_WITH_LONG_SECRET,直接跑起来等于没加密- 数据库密码必须改。compose 里的
STRONG_DB_PASSWORD是占位符,两处(DATABASE_URL和POSTGRES_PASSWORD)要改成同一个值
五、部署步骤
官方安装文档的步骤很清晰,这里照做并补齐细节。
第一步:安装 Docker
官方给的是 Ubuntu/Debian 的完整命令:
# Add Docker's official GPG key:
sudo apt-get update -qqy
sudo apt-get install ca-certificates curl -qqy
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# Add the repository to Apt sources:
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update -qqy
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin -qqy
装完验证:
docker --version
docker compose version
如果你用的是国内服务器,docker 官方源可能拉不动,换阿里云镜像源或者用系统自带的 docker.io 包都可以,只要版本够新。
第二步:创建目录并拉取官方 compose
mkdir docmost
cd docmost
curl -O https://raw.githubusercontent.com/docmost/docmost/main/docker-compose.yml
这一步直接把官方仓库里的 docker-compose.yml 拉到本地,保证配置和最新版一致。
第三步:修改 compose
打开文件:
vi docker-compose.yml
官方 compose 的完整内容是这样(这份就是上一步拉下来的,列出来方便对照):
services:
docmost:
image: docmost/docmost:latest
depends_on:
- db
- redis
environment:
APP_URL: "http://localhost:3000"
APP_SECRET: "REPLACE_WITH_LONG_SECRET"
DATABASE_URL: "postgresql://docmost:STRONG_DB_PASSWORD@db:5432/docmost"
REDIS_URL: "redis://redis:6379"
ports:
- "3000:3000"
restart: unless-stopped
volumes:
- docmost:/app/data/storage
db:
image: postgres:18
environment:
POSTGRES_DB: docmost
POSTGRES_USER: docmost
POSTGRES_PASSWORD: STRONG_DB_PASSWORD
restart: unless-stopped
volumes:
- db_data:/var/lib/postgresql
redis:
image: redis:8
command: ["redis-server", "--appendonly", "yes", "--maxmemory-policy", "noeviction"]
restart: unless-stopped
volumes:
- redis_data:/data
volumes:
docmost:
db_data:
redis_data:
必须改三处:
1. APP_URL —— 改成你实际访问的地址。上线后走域名就写 https://docs.your-domain.tld。
2. APP_SECRET —— 生成一个长随机串:
openssl rand -hex 32
把输出填进去。这个值用于加密会话,泄露等于所有登录态可伪造,务必随机、务必别提交到 Git。
3. DATABASE_URL 和 POSTGRES_PASSWORD —— 两处要改成同一个新密码:
openssl rand -base64 24
改完应该是这样:
DATABASE_URL: "postgresql://docmost:你生成的密码@db:5432/docmost"
environment:
POSTGRES_DB: docmost
POSTGRES_USER: docmost
POSTGRES_PASSWORD: 你生成的密码
密码里如果包含 @、:、/ 这些 URL 特殊字符,在 DATABASE_URL 里必须做 URL 编码,否则连接串会被截断。最省事的做法是只用字母和数字,别用符号。
顺带一个安全加固建议:给 ports 加上 127.0.0.1 前缀,只监听本机,外部访问统一走反代:
ports:
- "127.0.0.1:3000:3000"
第四步:启动
docker compose up -d
第一次启动会拉三个镜像(docmost、postgres:18、redis:8),视网络情况需要几分钟。
看启动日志:
docker compose logs -f docmost
等到日志不再刷数据库迁移相关内容,说明初始化完成。
第五步:初始化工作区
浏览器打开 http://<服务器IP>:3000,会引导你创建工作区、设置管理员账号。填完就能进主界面。
第六步:配反向代理(强烈建议)
Caddy 版本:
docs.your-domain.tld {
reverse_proxy 127.0.0.1:3000
}
Nginx 版本(注意 WebSocket 要放行,否则实时协作不工作):
server {
listen 443 ssl http2;
server_name docs.your-domain.tld;
ssl_certificate /etc/letsencrypt/live/docs.your-domain.tld/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/docs.your-domain.tld/privkey.pem;
client_max_body_size 100M;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket 支持(实时协作必需)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
配好后务必把 compose 里的 APP_URL 改成 https://docs.your-domain.tld,然后重启:
docker compose up -d
APP_URL 不匹配是「登录后一直跳回登录页」的头号原因。
六、配置参数详解
应用容器
| 变量 | 必填 | 说明 |
|---|---|---|
APP_URL |
是 | 对外访问地址,必须与浏览器地址栏完全一致(含协议) |
APP_SECRET |
是 | 会话加密密钥,用 openssl rand -hex 32 生成,不要复用 |
DATABASE_URL |
是 | PostgreSQL 连接串,格式 postgresql://用户:密码@主机:端口/库名 |
REDIS_URL |
是 | Redis 连接串,默认 redis://redis:6379 |
PORT(可选) |
否 | 容器内监听端口,默认 3000 |
数据库容器
| 变量 | 说明 |
|---|---|
POSTGRES_DB |
库名,默认 docmost,改了要同步改 DATABASE_URL |
POSTGRES_USER |
用户名,默认 docmost |
POSTGRES_PASSWORD |
密码,必须改,且与 DATABASE_URL 里的一致 |
注意数据目录是 /var/lib/postgresql(PostgreSQL 18 的路径),不是老版本的 /var/lib/postgresql/data。自己改 compose 时别照抄旧教程的路径,否则数据会写丢。
Redis 容器
官方给的启动参数:
redis-server --appendonly yes --maxmemory-policy noeviction
两个参数都有讲究:
--appendonly yes:开启 AOF 持久化。Redis 里存着会话和实时协作的中间状态,重启丢了会导致在线用户掉线--maxmemory-policy noeviction:内存满了不淘汰 key,而是报错。这个不能改成 LRU 类策略,否则会话被淘汰会出现莫名掉线
数据卷
| 卷 | 容器内路径 | 内容 |
|---|---|---|
docmost |
/app/data/storage |
附件、图片、导出文件 |
db_data |
/var/lib/postgresql |
所有文档数据 |
redis_data |
/data |
AOF 文件 |
三个卷都要备份,其中 db_data 最关键。
七、启动与运维
# 启停
docker compose up -d
docker compose stop
docker compose restart
# 只重启应用(改配置后常用,不动数据库)
docker compose restart docmost
# 日志
docker compose logs -f --tail=100 docmost
docker compose logs -f --tail=50 db
# 资源占用
docker stats
备份(三件套):
# 1. 数据库逻辑备份(推荐,可跨版本恢复)
docker compose exec -T db pg_dump -U docmost docmost | gzip > docmost-db-$(date +%F).sql.gz
# 2. 附件(命名卷里的内容)
docker run --rm -v docmost_docmost:/data -v $(pwd):/backup alpine \
tar czf /backup/docmost-storage-$(date +%F).tar.gz -C /data .
# 3. compose 与配置
cp docker-compose.yml docker-compose.yml.bak-$(date +%F)
第一条是热备份,不用停服务;如果要绝对一致,先 docker compose stop docmost 再执行。
定时备份示例(写进 crontab,每天凌晨 3 点):
0 3 * * * cd /opt/docmost && docker compose exec -T db pg_dump -U docmost docmost | gzip > /backup/docmost-$(date +\%F).sql.gz
八、实操验证
1. 三个容器是否都在
docker compose ps
预期三行,状态都是 Up。注意 db 和 redis 可能显示 Up (healthy)。
2. 应用端口
curl -I http://127.0.0.1:3000
返回 200 或 302。
3. 数据库连得上
docker compose exec db psql -U docmost -d docmost -c '\dt'
能看到一堆表(users、spaces、pages 之类),说明迁移跑成功了。
4. 工作区能进
浏览器打开地址,能登录进主界面,左侧能看到默认空间。
5. 实时协作真的生效(这一步必须做,因为它是核心卖点)
开两个浏览器窗口(一个正常、一个无痕),用两个不同账号登录,同时打开同一篇文档,在 A 窗口打字,看 B 窗口是不是立刻出现。
如果 B 窗口要刷新才更新,说明 WebSocket 没通,回去检查反代的 Upgrade 头。
6. 附件上传
新建页面,拖一张图进去,上传成功后刷新页面看图片还在。再确认附件落了卷:
docker compose exec docmost ls -lh /app/data/storage
7. 权限生效
建一个空间,把权限设成「仅特定成员可见」,用另一个账号登录,确认看不到这个空间。
九、故障排查
登录后立刻跳回登录页 / 一直要求登录
APP_URL 和实际访问地址不一致。这是最常见的问题,尤其配了 HTTPS 之后忘了改。
docker compose exec docmost env | grep APP_URL
输出必须和你浏览器地址栏完全一致,包括 https:// 和端口。
页面能开但实时协作不同步
反代没放行 WebSocket。浏览器 F12 → Network → WS,看有没有连接失败的记录。Nginx 加上前面那段 proxy_set_header Upgrade,Caddy 默认支持不用改。
容器起不来,日志报数据库连接失败
docker compose logs db | tail -30
常见原因:
POSTGRES_PASSWORD和DATABASE_URL里的密码不一致- 密码里有特殊字符没做 URL 编码
db还没初始化完,docmost就启动连不上——depends_on只保证启动顺序,不保证服务就绪,等几十秒通常会自己重试成功
Postgres 报权限错误 / 数据目录空
PostgreSQL 18 的数据目录是 /var/lib/postgresql,如果你照旧教程写成了 /var/lib/postgresql/data,初始化会失败。检查 compose 里的挂载路径。
上传大附件报 413
反代的请求体限制。Nginx 加 client_max_body_size 100M;(按需调大)。
Redis 报 OOM 或会话莫名丢失
--maxmemory-policy 被改成了 allkeys-lru 之类的策略,内存一紧就把会话淘汰了。改回官方给的 noeviction,同时给容器加内存限制或扩机器内存。
升级后白屏
浏览器缓存了旧的静态资源。强制刷新(Ctrl+Shift+R),或者清一下 CDN 缓存。
十、升级、回滚与卸载
升级
cd docmost
docker compose pull
docker compose up -d
Docmost 启动时会自动跑数据库迁移,日志里能看到 migration 相关输出,等它跑完即可。
升级前必须备份数据库。迁移是单向的,跨大版本降级大概率读不了新库。
回滚
镜像换回具体版本标签:
image: docmost/docmost:0.22.0
docker compose up -d
同时还原升级前的数据库备份:
docker compose stop docmost
docker compose exec -T db psql -U docmost -d docmost < docmost-db-2026-11-02.sql
docker compose start docmost
注意:如果新版本已经改了表结构,直接灌旧 dump 可能会因为表已存在而报错。最稳的做法是把 db_data 卷一起回滚——升级前用卷快照或者 docker run --rm -v ... tar 打成 tar 包。
卸载
cd docmost
docker compose down
# 删除数据卷(确认数据不再需要!)
docker compose down -v
# 删除目录
rm -rf docmost
docker compose down 默认保留卷,数据还在。加 -v 才会连数据一起删。执行 -v 前一定要确认备份存在。
十一、商用许可
Docmost 采用双许可模式,这一点在官方 README 里写得很明确。
核心:AGPL-3.0
主体代码(core)是 AGPL-3.0:
- 可以商用,公司内部部署、给团队用,完全免费,不需要授权
- 可以修改,但如果修改版作为网络服务对外提供,必须公开修改后的源码
- 可以分发,需附带许可证和源码
企业版:Enterprise License
README 明确圈出了这几个目录适用企业许可:
apps/server/src/ee
apps/client/src/ee
packages/ee
这些是企业功能(Enterprise Edition)的代码,不属于 AGPL 范围,不能按开源协议自由使用。要用这些功能,需要购买 Docmost 的商业授权。
实操判断
| 你的场景 | 是否合规 |
|---|---|
| 公司内部部署一套,用社区版功能 | 完全合规,免费 |
| 基于核心代码二次开发,内部使用 | 合规 |
| 基于核心代码改一版,对外提供 SaaS | 需开源你的修改(AGPL) |
想用 /ee 目录里的企业功能 |
需购买商业授权 |
| 把 Docmost 打包进商业产品售卖 | 需同时评估 AGPL 与企业许可,建议联系官方 |
对绝大多数「自己团队用文档」的场景,AGPL 不会带来任何额外负担,直接部署就行。