☰
docmost 开源部署指南:用 Docker Compose 搭建自托管知识库
2026/10/5 11:05:29 网站建设 项目流程

文档管理系统的选择,其实是个老生常谈但永远绕不开的话题

我前阵子帮团队折腾文档协作平台,翻遍了市面上的主流方案,Confluence 功能全但太重,Notion 数据不在自己手里,语雀倒是省心,可企业内部用总有点隔靴搔痒的感觉。最后落在了一个叫 docmost 的开源项目上,折腾了几天把它部署到了内网服务器,用起来意外地顺手。

docmost 是一款开源的文档管理软件,主打的是wiki 式协作,支持实时协同编辑、评论、权限管理、Markdown/WYSIWYG 双模式编辑,还能跟 Google Drive 和 Slack 做集成。最关键的是,它可以完全自托管,数据、权限、隐私都在自己手里。对于团队内部知识库、个人笔记归档、项目文档沉淀这类场景,部署一套 docmost 基本能覆盖八成需求。

这篇文章就是把我当时的部署过程、踩过的坑、以及一些值得留意的细节整理出来,给打算自建文档系统的朋友一个参考。无论你是用 Docker 快速起一个试用实例,还是想在内网服务器上做成正式环境,接下来的内容应该都能直接用上。


1. 部署前要先想明白的几件事

1.1 为什么选 docmost 而不是其他方案

先说结论:如果你需要的是一个“能写、能协作、能管权限、数据在自己手里”的文档系统,docmost 是个非常平衡的选择。

Confluence 的问题不只是贵,部署架构也重,对 Docker 内存的要求动辄几个 GB,小团队用起来有点杀鸡用牛刀。而各类在线文档服务虽然体验好,但数据在别人服务器上,对于有保密要求的团队来说基本可以一票否决。

docmost 的系统架构相对轻量,官方推荐用 Docker Compose 部署,本质上就是docmost 的 Node.js 服务端 + Redis 做缓存/队列 + 数据库存数据,数据库支持 PostgreSQL 和 SQLite。单机部署的情况下,两核四G的服务器跑起来毫无压力,内存占用大约在 400MB 到 600MB 之间,比不少同类产品省得多。

部署形式灵活是你选择它的重要理由:既可以像我用 Docker 容器化跑,也可以直接跑二进制可执行文件裸装,后一种方式适合那种不想引入 Docker、对性能有极致要求的服务器。不过日常场景里我用 Docker 的方式更多,因为升级、回滚都方便。

1.2 部署拓扑和资源评估

先看一下我实际使用的部署拓扑,这是最开始就要想清楚的:

客户端浏览器 ↓ HTTPS/HTTP 反向代理(Nginx,可选用) ↓ docmost 容器(端口 3000) ↓ Redis 容器(端口 6379) ↓ PostgreSQL 容器(端口 5432)

这套结构最常规也最稳。docmost 容器对外暴露 3000 端口,Redis 和 PostgreSQL 不需要暴露到宿主机外面,Docker 内网通信即可。

硬件配置上,我拿一台 2 核 2G 的云主机做过一次压力测试,同时三个人在线编辑、其中一个人做全文搜索,系统负载比较平稳,CPU 偶尔飙到 70% 以上但不会长期占满。如果你们团队人数在 20 人以内,2 核 4G 完全够用;超过 20 人或者要跑全文索引,建议直接 4 核 8G。

存储方面,docmost 的数据库和上传文件都需要持久化。如果数据量不大,用 Docker 卷挂在宿主机目录即可;如果上传附件特别多,建议把 docmost 的附件目录单独挂到一块更大的数据盘上,避免系统和数据抢磁盘 I/O。

提示:docmost 支持 SQLite,但只适合纯个人使用或测试。多人协作场景建议用 PostgreSQL,并发锁和查询优化能力不是一个量级。

1.3 选择部署方式的核心依据

docker compose 是我最推荐的部署方式,大概三个原因:

第一,依赖管理清晰。docmost 、Redis、PostgreSQL 三个容器由 Compose 编排,一条命令全部拉起和销毁,不用手工去装 Node.js、Redis、Postgres 的一堆依赖,尤其适合那些不想在服务器上装太多运行时组件的朋友。

第二,升级和回滚极其方便。改个镜像标签,docker compose up -d 就完成了版本切换。万一新版本有兼容问题,重新指向旧镜像标签再拉一次就回滚了,对生产环境非常友好。

第三,环境隔离更彻底。docmost 是个 Node 应用,依赖版本冲突是常见问题,容器化后这些全都被隔离在镜像内部,不会污染宿主机环境。

当然,裸装方式也有它的场景。如果你的服务器本身内存比较紧张(比如 1G 或以下),去掉 Docker 这一层能省掉一部分开销。或者你已经有比较成熟的运维体系,全部用 systemd 托管进程,那裸装更符合现有规范。我个人的建议是,除非你没得选,否则优先 Docker Compose,省心。


2. 核心配置拆解:这些参数不看仔细,后面有你哭的时候

2.1 docmost 环境变量逐个讲

docmost 的配置基本靠环境变量驱动,这是最容易踩坑的地方。官网给了一堆变量,但实际部署只需要关注几个:

环境变量作用我的实际配置注意事项
APP_URL对外访问地址http://192.168.1.100:3000这里必须填浏览器访问的地址,填错了会导致邮件里的链接和分享链接失效
APP_PORT容器内部监听端口3000一般不用动
DATABASE_URL数据库连接串postgresql://docmost:docmost@postgres:5432/docmost注意数据库主机名用的是 Compose 里的服务名,不是 127.0.0.1
REDIS_URLRedis 连接串redis://redis:6379同上
SECRET_KEY会话/加密密钥自己生成的一长串随机字符生产环境必须设置,否则会有安全提醒
JWT_SECRETJWT 签名密钥另一串随机字符跟 SECRET_KEY 区分开
FILE_STORAGE文件存储位置local或s3默认本地,上云了再改 S3

这么多变量里,最值得强调的就是APP_URL。我最初部署测试环境的时候偷懒没设这一项,结果通过其他同事的电脑访问文档,邮件通知里的链接带着 127.0.0.1,点开全是不通的。所以部署完成之后,第一件事就是把最终访问地址填进去。

SECRET_KEY也是个容易忽略的点。如果你用默认值或者不设置,docmost 启动会提示不安全,多人登录后还有潜在的安全风险。生成方法很简单,Linux 上用openssl rand -hex 32生成两串 32 字节的十六进制字符串,分别放进两个 key 即可。

2.2 数据库初始化说明

docmost 首次启动时会自动创建数据库表结构,不需要手工执行 SQL 脚本。但我个人建议在正式使用之前,先创建一个专门给 docmost 用的 PostgreSQL 用户和数据库,不要直接拿 postgres 超级用户来跑。

我当时的做法是这样的:

CREATE DATABASE docmost; CREATE USER docmost WITH PASSWORD '这里填一个强密码'; GRANT ALL PRIVILEGES ON DATABASE docmost TO docmost;

然后再把DATABASE_URL配成postgresql://docmost:密码@postgres:5432/docmost。

表面上看直接用超级用户省事,但一旦出了问题或者想迁移数据,权限控制做的不好会很被动。另外,docmost 新建空间、邀请成员这些操作都依赖数据库权限,提前把账号权限界定清楚能省掉后续不少麻烦。

2.3 Redis 在这里的角色

可能有人会问,一个文档协作系统为什么还需要 Redis ?docmost 用了 Redis 做两件事:一是会话和缓存存储,保存用户的登录态和一些频繁读取的数据;二是任务队列,像导出 PDF、发送邮件通知这类异步任务都要经过队列处理。

所以在部署的时候,Redis 不能省,也别简化成 SQLite 里的内存表,编辑器协同时的状态同步会对 Redis 产生不小的读写压力。用 Docker 装一个官方 redis:7 镜像就行,不赘述。


3. 实操过程:从零开始跑起一套能用的环境

3.1 服务器环境与前置准备

我用的是 Ubuntu 22.04 LTS,基本条件如下:

  • 2 核 4G 内存的云主机
  • Docker 24.0+ 和 Docker Compose v2
  • 域名已解析到服务器 IP(如果有域名的话)
  • 服务器上开放了 80/443 或 3000 端口的防火墙规则

先检查 Docker 是否装好:

docker --version docker compose version

如果系统上还没有 Docker 环境,最快的方式是用官方脚本安装:

curl -fsSL https://get.docker.com | sh systemctl enable --now docker

在 VPS 环境下,安装结束后建议把当前用户加进 docker 组,避免每条命令都要 sudo:

usermod -aG docker $USER newgrp docker

3.2 编写 Compose 文件

我当时的目录结构很简单:

/mnt/docmost/ ├── docker-compose.yml ├── .env └── data/ ├── postgres/ └── storage/

其中docker-compose.yml内容如下,我作了简化和注释:

services: docmost: image: docmost/docmost:latest container_name: docmost restart: unless-stopped depends_on: - postgres - redis ports: - "3000:3000" environment: - APP_URL=http://你的服务器IP:3000 - APP_PORT=3000 - DATABASE_URL=postgresql://docmost:你的数据库密码@postgres:5432/docmost - REDIS_URL=redis://redis:6379 - SECRET_KEY=这里填一串随机字符 - JWT_SECRET=这里填另一串随机字符 - FILE_STORAGE=local volumes: - ./data/storage:/app/data/storage postgres: image: postgres:16-alpine container_name: docmost_postgres restart: unless-stopped environment: - POSTGRES_DB=docmost - POSTGRES_USER=docmost - POSTGRES_PASSWORD=你的数据库密码 volumes: - ./data/postgres:/var/lib/postgresql/data redis: image: redis:7-alpine container_name: docmost_redis restart: unless-stopped volumes: - ./data/redis:/data

把上面的你的服务器IP、密码、密钥换掉就可以直接用。注意container_name不要跟其他容器重复,不然 Docker 会报冲突。更规范的做法是把密码和密钥单独放到.env文件里,通过${变量名}引用,这样 docker-compose.yml 可以直接进 Git 仓库而不泄露敏感信息。

3.3 启动与初始化验证

配置文件就绪后,执行:

cd /mnt/docmost docker compose up -d

第一次启动会自动拉取镜像,等一会儿后观察容器状态:

docker compose ps

正常情况下三个容器都是 Up 状态。然后看日志:

docker compose logs docmost

看到类似 “listening on 0.0.0.0:3000” 的日志,基本就起来了。这时在浏览器访问http://服务器IP:3000,首次进入会跳转到初始化注册页面,创建一个管理员账号。这个页面比较关键,第一个注册的用户就是系统管理员,后续邀请加入的成员都由这个人审核和管理。

注意:数据库卷映射和存储卷映射要对应用户权限。docmost 容器默认以 node 用户运行,如果宿主机上的数据目录权限不对,启动时可能出现 “EACCES” 错误。我当时就遇到过 storage 目录权限问题,解决办法是chown -R 1000:1000 ./data/storage,因为容器内 node 用户的 UID 恰好是 1000。

3.4 配置 Nginx 反向代理(可选但推荐)

如果只是内网测试,直接 IP 访问 3000 端口就可以。但正式使用场景,我强烈建议在前面加一层 Nginx 反向代理,理由有三:

第一,统一入口端口。团队成员只需要记一个https://doc.域名.com,不用关心后端是 3000 还是 80。

第二,可以挂 SSL 证书。明文 HTTP 传输文档内容,在局域网里还好,公网环境就有点风险了。

第三,方便后续加安全策略,比如 IP 白名单、限流等。

我的 Nginx 配置片段:

server { listen 80; server_name doc.example.com; location / { proxy_pass http://127.0.0.1:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; 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; proxy_read_timeout 3600s; } }

里面有两处是文档协作软件特有的:

  • 升级头:docmost 的实时编辑用了 WebSocket,所以必须把 Upgrade 和 Connection 两个头传给后端,否则编辑器会频繁断连。
  • 读取超时:文档导出和批量操作时,后端处理时间可能很长,默认 60 秒的 read 超时会过早掐断,所以我调成了 3600 秒。

配置完记得:

nginx -t systemctl reload nginx

再顺带提一句,如果你用的是 Docker 里的 Nginx,要确保proxy_pass http://docmost:3000里的 docmost 是 Compose 网络里可解析的容器名,不能写 127.0.0.1。

3.5 常见问题与排查技巧实录

部署过程中我遇到过几个比较典型的坑,整理成速查表:

现象可能原因解决方法
浏览器一直提示 502 Bad GatewayNginx 代理指向的端口不对,或 docmost 容器未启动先docker compose ps确认容器状态,再docker compose logs docmost看具体报错
注册后收不到邀请邮件没有配置 SMTP,或被系统当作测试环境开发环境直接忽略,正式环境在管理后台填入 SMTP 参数
编辑器保存内容后刷新丢失数据库连接串写错了主机名,导致 docmost 连不上 PostgreSQL确认数据库连接串里的 host 是 Compose 服务名postgres
页面能开但登录总是失败Redis 连接异常或者 SECRET_KEY 不一致检查 Redis 是否在运行,以及环境变量里 SECRET_KEY 是否被多次改动
上传文件报错storage 卷权限不对chown -R 1000:1000 data/storage后再启动容器

其中两个最容易被忽略的地方:

一是depends_on并不能保证数据库完全就绪。Compose 里的depends_on只是控制容器启动顺序,不会等待数据库做完初始化。如果第一次启动时数据库还在初始化,docmost 可能报连接失败,但通常只要等几秒后重启容器就好:

docker compose restart docmost

二是环境变量改了之后必须重建容器才生效。很多人改完docker-compose.yml里的环境变量后直接docker compose restart,结果发现配置没变。这是因为 restart 不会重建容器,环境变量只有在容器创建时才会注入。正确做法是:

docker compose up -d --force-recreate docmost

4. 更进一步:怎么让你的 docmost 真正好用

4.1 数据备份策略

自托管系统的第一原则就是:任何时刻数据都要可恢复。docmost 的数据包括三块:PostgreSQL 数据库、Redis 缓存数据、本地 storage 目录中的附件。

备份的优先级很明显:数据库最重要,附件其次,Redis 基本不用备份,丢了重启就有。

我用的是一个简单的 cron 脚本,每天凌晨备份数据库和附件目录:

#!/bin/bash BACKUP_DIR=/mnt/backups/docmost mkdir -p $BACKUP_DIR docker exec docmost_postgres pg_dump -U docmost docmost | gzip > $BACKUP_DIR/docmost_$(date +%F).sql.gz tar czf $BACKUP_DIR/storage_$(date +%F).tar.gz -C /mnt/docmost/data storage find $BACKUP_DIR -type f -mtime +7 -delete

然后 crontab 加上定时执行:

0 2 * * * /root/backup_docmost.sh

恢复也很简单,数据库连接串里的库和用户重建好之后,用 zcat 导回去;附件直接解压回 storage 目录。

提示:如果用了 S3 存储,备份就只剩数据库这一环,附件由对象存储的多副本机制兜底,可以省掉 tar 这一步。

4.2 用户角色与权限设计

docmost 的权限体系围绕空间(Space)展开,每个空间下可以设置成员的权限级别,包括只读、可评论、可编辑、创建者、空间管理员等。

我实际用下来的建议是:

  • 空间管理员数量限制在 1-2 人,避免权限分散。
  • 默认新成员只读,等他们熟悉协作模式后再开放编辑权限。
  • 敏感项目单独建空间,别混在一个大空间里。
  • 用空间分类把研发、产品、市场等团队的文档隔离,一目了然。

另外,docmost 支持锁定页面,防止某些正式发布的文档被误改。公司制度、对外合同、流程规范这类文档,写完定稿之后就让空间管理员锁定页面,只留全员只读。这个功能在内部推进的时候非常实用,能大幅减少“谁把正文改了”这种沟通成本。

4.3 编辑器功能与外部集成的取舍

docmost 的编辑器本身支持 Markdown 和块编辑,日常写技术文档、会议纪要完全够用。实时协同编辑用的是类似 Notion 的块概念,多人同时编辑一个页面时,光标位置、选中的块都是实时可见的,实际用下来协同体验比我预想的好很多。

比较让我惊喜的小功能:

  • 支持代码块,代码高亮效果不错。
  • 用/命令可以快速插入表格、图片、待办清单、公式等块。
  • 支持全文搜索,标题、正文都能搜到,对知识库场景很重要。
  • 支持一键导出 PDF 和 Markdown。

集成方面,默认支持 Google Drive 和 Slack。特殊情况用不到的话,在集成设置里关掉就行,也能省掉多余的外部 API 调用。

4.4 和 Clawdbot 之类工具的联动思路

其实现在不少团队会把 docmost 跟本地部署的 AI 工具、自动化机器人配合使用,形成一套完整的内容生产与分发流水线。比如通过 Clawdbot 这类自动化工具把手动上传文档、定时整理归档的动作串起来,或者把内部工作流中产出的内容自动同步进 docmost 空间,减少人工搬运。

如果你也在折腾本地部署相关的东西,docmost 可以作为这些工具统一的内容存储层。它提供 API,支持用 token 方式做服务端鉴权,第三方脚本可以通过 API 创建空间、创建页面、更新文档内容。只要不对外暴露管理端,配合自动化工具使用,整个知识库可以变成一个自动生长、持续沉淀的系统。

我在具体项目中是把 docmost 和内部机器人做了联动:代码仓库里发生的变更说明、发布记录、重要会议总结,都由机器人自动整理成 Markdown 写入 docmost 对应空间。团队成员再也不用纠结文档过期的问题,因为大部分内容根本不需要人工维护。


5. 部署完成之后,检查一遍这几个细节才算真正落地

5.1 安全强化

如果你部署的位置是公网环境,请一定不要裸奔:

  • 关闭服务器上不需要的端口,最少只留 80/443 和 SSH。
  • Nginx 层全部启用 HTTPS,证书可以用你自己的证书体系,也可以用自动化脚本申请和管理。
  • docmost 管理后台用强密码,成员账号开启邮箱验证(如果配置了 SMTP)。
  • 定期为所有容器升级镜像版本,关注 docmost 的 GitHub Releases 页面。

对于纯内网环境,至少也要设置访问来源限制,防止脚本扫描打到 3000 端口上。Nginx 可以做一层 IP 白名单,只允许公司网段访问,操作很简单,效果却很明显。

5.2 性能优化方向

之前提过 2C4G 的机器在多人并发下表现不错,但如果你的团队成员超过 20 人,可以考虑两个优化方向:

一是把 docmost 容器单独部署到一台更高的服务器上,和数据库、Redis 分离。这个有点重了,配合容器化其实不算难,但维护成本会高一些。

二是给 Redis 和 PostgreSQL 分配合理的资源上限。Docker 默认不限制容器内存,所有容器共享宿主机内存,一旦某容器内存增长异常,其他服务可能被拖垮。可以在 Compose 文件里给每个服务加deploy.resources.limits:

services: postgres: image: postgres:16-alpine ... deploy: resources: limits: memory: 1g redis: image: redis:7-alpine ... deploy: resources: limits: memory: 512M

内存限制不代表性能上限,反而能防止单个服务异常导致的雪崩,这个习惯我建议从第一天就养成。

5.3 团队初始化的最佳实践

最后说说部署完成后怎么让团队顺利用起来。这是最容易忽略的非技术环节,但往往决定一套系统是转起来还是吃灰。

我踩过的坑是,直接把 docmost 丢给团队说“你们用吧”,结果一周后没人用。后来我调整了方式:

  • 先在里面把团队现有的高频文档搬过去,比如周报模板、项目复盘模板、研发规范、交接文档,让第一天打开就有内容。
  • 把 docmost 设成团队首页,收录在浏览器书签和团队导航页里。
  • 由一到两个人的核心用户带动使用,快速产出协作示范。
  • 定期整理优秀文档作为范例,让大家看到协作价值。

一旦团队形成“遇到文档先查 docmost,写完先同步进 docmost”的习惯,这套自托管系统就真正有生命力了。


我在实际部署中最大的体会是,docmost 并不是一个功能上花哨的工具,但它在“够用”和“可控”之间找到了很好的平衡点。尤其对于不想把数据托管在第三方平台、又希望拥有协作体验的团队来说,docmost 是一个值得花半天时间认真折腾的方案。

如果后面的版本能继续把移动端体验打磨得更好一些,它可能真的会成为 Confluence 之外,很多团队文档底座的最佳选择。最后再分享一个小技巧:把 docmost 的管理后台入口放到一个不那么明显的路径下,比如通过 Nginx 加一层路径前缀,能躲掉不少扫描器的自动探测,虽然不至于高枕无忧,但能让日志干净不少。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询