Loading...

文章背景图

Docmost:开源团队 Wiki|实时协作文档系统部署与配置

2026-11-02
1
- 字
- 分钟
|

团队文档这件事,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 更适合放在内网。

三、官方链接

四、环境要求

项目 要求
系统 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

常见原因:

  1. POSTGRES_PASSWORD 和 DATABASE_URL 里的密码不一致
  2. 密码里有特殊字符没做 URL 编码
  3. 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 不会带来任何额外负担,直接部署就行。

评论交流

文章目录