Docmost 0.96.0 配置参数详解
逐项讲解 Docmost 0.96.0 环境变量:参数总览表、启动期校验规则与修改生效流程;APP_SECRET/PORT/JWT 有效期/IFRAME 嵌入白名单/上传大小限制/邮件驱动/Redis 认证等核心参数附真实改动实测与回显,含生产配置模板与 6 个常见问题。
Docmost 0.96.0 配置参数详解
目标:对 Docmost 0.96.0 的环境变量做逐项讲解——参数作用、默认值、校验规则与修改生效方式,核心参数附真实改动实测(含回显)。实测基于《Docmost Docker Compose 部署指南》完成的标准部署(端口 8108);组件背景见《Docmost 0.96.0 介绍与选型指南》。
一、环境信息
| 项目 | 值 |
|---|---|
| 服务器 IP(内网) | 192.168.146.128(网卡 ens33) |
| 操作系统 | Ubuntu Linux(内核 6.x,x86_64) |
| 部署方式 | 官方 Docker Compose 结构(应用 + PostgreSQL 18 + Redis 8),见《Docmost Docker Compose 部署指南》 |
| Docmost 版本 | 0.96.0 |
| 对外端口 | 8108 → 3000(应用默认内部端口 3000) |
| 数据目录 | /opt/data/quzuo/docmost-0.96.0/{storage,db,redis} |
| 管理员账号 | admin(admin@example.com)/ q1w2e3r4 |
| 测试日期 | 2026-10-18 |
本次实测的部署基线环境变量(docker-compose.yml 的 environment: 段):
APP_URL: 'http://192.168.146.128:8108'
APP_SECRET: 'f35f9bba2a2204a026106e40fec4d3fd9d4a854708464ec522505ad88a058cc2'
DATABASE_URL: 'postgresql://docmost:q1w2e3r4@db:5432/docmost'
REDIS_URL: 'redis://redis:6379'
实测过程中的临时改动(PORT、JWT_TOKEN_EXPIRES_IN、IFRAME_、FILE_UPLOAD_SIZE_LIMIT、MAIL_ 等)均验证后还原为基线值。
二、前置条件
- 已按《Docmost Docker Compose 部署指南》完成部署并初始化工作区与管理员(服务监听 8108,
curl -s -o /dev/null -w '%{http_code}' http://localhost:8108返回 200)。 - 部署目录
/opt/data/quzuo/docmost-0.96.0/下有可编辑的docker-compose.yml,宿主机装有 docker 与 docker compose 插件。 - 理解 Docmost 配置模型:全部参数为环境变量驱动,无独立配置文件。参数分两类——必填项缺失或不合规时启动直接失败;可选项缺省走内置默认值。
三、参数查看与修改方式
3.1 查看参数
- 看生效值:进应用环境查看当前变量(以查看默认端口变量为例):
docker compose exec docmost printenv | grep -E '^(PORT|APP_URL|MAIL_DRIVER|STORAGE_DRIVER)='
回显(基线部署,未显式设置的可选项不出现,即走内置默认):
APP_URL=http://192.168.146.128:8108
- 看启动加载结果:应用启动日志会显式回显监听地址(含
APP_URL),是核对APP_URL/PORT是否生效的第一现场(见 5.2 节)。 - 看权威默认值:官方环境变量文档 https://docmost.com/docs/self-hosting/environment-variables ;更精确的默认值在应用内
apps/server/dist/integrations/environment/environment.service.js(本文"默认值"均以该源码实测核对为准,个别与官方文档不一致处单独标注)。
3.2 修改与生效流程
环境变量驱动,无热加载:改编排文件的 environment: 段后重建服务生效。
cd /opt/data/quzuo/docmost-0.96.0
vi docker-compose.yml # 在 docmost 服务的 environment: 段增删变量
docker compose up -d # 重建服务生效
docker compose logs --since 1m docmost # 观察启动日志确认
⚠️ 注意 YAML 缩进与键名重复:实测中曾在同一
environment:段把REDIS_URL写了两遍,docker compose up -d报 YAML 解析错误。可用docker compose config先校验。
3.3 启动期校验规则
应用启动时对关键参数做强校验(源码 environment.validation.js,实测核对),不满足则启动失败并明确报错:
| 参数 | 校验规则(实测) |
|---|---|
APP_SECRET | 必填;长度 ≥ 32;不得为官方示例占位值(REPLACE_WITH_LONG_SECRET 会被拒绝) |
DATABASE_URL | 必填;必须是合法 URL 且协议为 postgres/postgresql |
REDIS_URL | 必填;必须是合法 URL 且协议为 redis |
APP_URL | 可选;设置时必须是合法 http(s) URL |
MAIL_DRIVER | 可选;只允许 smtp / postmark(注意:默认值 log 不在校验白名单里,属未设置时的内置默认) |
STORAGE_DRIVER | 可选;只允许 local / s3 / azure |
SEARCH_DRIVER | 可选;只允许 database / typesense |
COLLAB_URL | 可选;设置时必须是合法 http(s) URL |
SUBDOMAIN_HOST | 云模式(CLOUD=true)下必填,须为合法域名 |
失败时启动中断,日志形如(APP_SECRET 过短的实测报错,见 5.1 节):
The Environment variables has failed the following validations: {"minLength":"APP_SECRET must be longer than or equal to 32 characters"}
Please fix the environment variables and try again. Exiting program...
四、参数总览
「默认值」列为 0.96.0 源码实测口径;「实测」列标注本文是否做了改动验证(✅ 附小节;☆ 为官方文档口径未复现;— 为企业版相关,本文未验证)。
| 参数 | 作用 | 默认值(0.96.0 实测口径) | 实测 |
|---|---|---|---|
APP_SECRET | 会话签名/加密密钥 | 无(必填) | ✅ 5.1 |
DATABASE_URL | PostgreSQL 连接串 | 无(必填) | ☆ 5.1 |
REDIS_URL | Redis 连接串 | redis://localhost:6379(compose 部署必须显式设置) | ✅ 5.1 |
APP_URL | 对外访问地址 | 空(可选) | ✅ 5.2 |
PORT | 服务监听端口 | 3000 | ✅ 5.2 |
JWT_TOKEN_EXPIRES_IN | 登录令牌有效期 | 90d | ✅ 5.3 |
IFRAME_EMBED_ALLOWED | 允许被第三方 iframe 嵌入 | false | ✅ 5.4 |
IFRAME_ALLOWED_ORIGINS | 嵌入来源白名单 | 空 | ✅ 5.4 |
STORAGE_DRIVER | 附件存储驱动 | local | ☆ 5.5 |
FILE_UPLOAD_SIZE_LIMIT | 单文件上传上限 | 50mb | ✅ 5.5 |
FILE_IMPORT_SIZE_LIMIT | 文件导入上限 | 200mb | ☆ |
MAIL_DRIVER | 邮件驱动 | log | ✅ 5.6 |
SMTP_HOST / SMTP_PORT | SMTP 服务器地址/端口 | 空 / 587 | ✅ 5.6 |
SMTP_SECURE | SMTP 是否直连 TLS | false | ☆ |
SMTP_IGNORETLS | 忽略 STARTTLS | false | ☆ |
SMTP_USERNAME / SMTP_PASSWORD | SMTP 认证 | 空 | ☆ |
MAIL_FROM_ADDRESS / MAIL_FROM_NAME | 发件人地址/名称 | 空 / Docmost | ✅ 5.6 |
SEARCH_DRIVER | 搜索引擎驱动 | database | ☆ 5.7 |
TYPESENSE_URL / TYPESENSE_API_KEY | Typesense 地址/密钥 | http://localhost:8108 / 空 | ☆ 5.7 |
DATABASE_MAX_POOL | 数据库连接池上限 | 10 | ☆ 5.7 |
COLLAB_URL | 独立协作服务地址 | 空 | ☆ 5.8 |
COLLAB_DISABLE_REDIS | 协作层禁用 Redis | false | ☆ 5.8 |
DRAWIO_URL | 自托管 Draw.io 地址 | 官方在线服务 | ☆ 5.8 |
GOTENBERG_URL | PDF 导出服务地址 | 空 | ☆ 5.8 |
DISABLE_TELEMETRY | 关闭匿名遥测 | false | ☆ 5.9 |
LOG_HTTP | 记录 HTTP 请求日志 | false | ☆ 5.9 |
DEBUG_MODE | 调试日志级别 | false | ☆ 5.9 |
AI_DRIVER / AI_VECTOR_DRIVER | AI 模型/向量驱动(企业) | — / pgvector | — |
SAML_*、OIDC_*、SCIM_* | SSO/用户同步(企业) | — | — |
💡 说明:
AI_*、SAML_*等企业版参数在企业许可下才生效,社区版设置不报错但无效果;本文不做验证,请以官方文档为准。
五、核心参数分类详解
5.1 连接与密钥类
5.1.1 APP_SECRET
应用级密钥,用于登录令牌(JWT)签名与全局数据加密,必填,≥32 字符。生成方式:
openssl rand -hex 32
回显:
f35f9bba2a2204a026106e40fec4d3fd9d4a854708464ec522505ad88a058cc2
实测(不合规值启动失败):把 APP_SECRET 改为 shortsecret 后 docker compose up -d,应用反复重启,日志:
The Environment variables has failed the following validations: {"minLength":"APP_SECRET must be longer than or equal to 32 characters"}
Please fix the environment variables and try again. Exiting program...
还原合法值后恢复正常。⚠️ 更换密钥后所有用户登录会话立即失效,需重新登录。
5.1.2 DATABASE_URL
PostgreSQL 连接串,必填,格式 postgresql://用户:密码@主机:5432/库名(compose 部署主机名为 db 服务名)。用户/密码/库名需与 PostgreSQL 服务的 POSTGRES_USER/POSTGRES_PASSWORD/POSTGRES_DB 三项一致。应用启动即迁移数据库(0.96.0 共 52 个迁移),连接失败时启动中断,日志出现 DatabaseMigrationService 报错。
5.1.3 REDIS_URL
Redis 连接串,必填,源码默认 redis://localhost:6379——compose 部署下 localhost 不通,必须显式指向 Redis 服务名。
实测(Redis 密码认证):给 Redis 加 --requirepass q1w2e3r4,应用改 REDIS_URL: 'redis://:q1w2e3r4@redis:6379'(注意密码前的冒号),重建后日志:
"msg":"RedisModule default: the connection was successfully established"
登录接口正常(login -> 200)。错误格式(漏冒号、明文密码段错误)会导致队列连接失败,页面可开但邮件等异步任务异常。
5.2 服务基础类
5.2.1 APP_URL
对外访问地址(协议 + IP/域名 + 端口)。它决定资源引用、分享链接、邮件里的链接地址;启动日志会回显它。
实测:基线 APP_URL: 'http://192.168.146.128:8108' 时启动日志末段:
"msg":"Listening on http://127.0.0.1:3000 / http://192.168.146.128:8108"
应用把「内部端口」与「对外 APP_URL」一并回显,可直接核对配置是否生效。反代/改端口后忘记同步 APP_URL 是常见坑(分享链接仍指旧地址)。
5.2.2 PORT
服务内部监听端口,默认 3000。一般无需修改;若 3000 与其他内部服务冲突,改 PORT 并同步调整端口映射的右侧值。
实测:设 PORT: '3100'、端口映射改为 8108:3100,重建后启动日志:
"msg":"Listening on http://127.0.0.1:3100 / http://192.168.146.128:8108"
curl -s -o /dev/null -w '%{http_code}' http://localhost:8108 返回 200。
5.3 认证与会话类
5.3.1 JWT_TOKEN_EXPIRES_IN
登录令牌有效期,默认 90d(90 天),支持 s/m/h/d 单位。
实测:设为 1h 重建后登录,解码返回的 authToken(JWT):
curl -s -X POST http://localhost:8108/api/auth/login \
-H 'Content-Type: application/json' \
-d '{"email":"admin@example.com","password":"q1w2e3r4"}' \
-D /tmp/jwt_headers.txt -o /dev/null -w 'login -> %{http_code}\n'
python3 - <<'EOF'
import re,base64,json
tok=re.search(r'authToken=([^;]+);',open('/tmp/jwt_headers.txt').read()).group(1)
d=json.loads(base64.urlsafe_b64decode(tok.split('.')[1]+'='*(-len(tok.split('.')[1])%4)))
print('delta_seconds:',d['exp']-d['iat'])
EOF
回显:
login -> 200
delta_seconds: 3600
令牌有效期精确变为 1 小时。⚠️ 官方环境变量文档对默认值的描述与源码不一致(文档写 30d,源码为 90d),以实测为准:默认部署解码令牌 exp - iat = 7776000(90 天),Cookie Expires 同步 90 天。
5.4 安全与嵌入类
5.4.1 IFRAME_EMBED_ALLOWED
是否允许本站被第三方页面 <iframe> 嵌入,默认 false(默认响应头 x-frame-options: SAMEORIGIN,只允许同源嵌入)。
实测:默认时响应头:
x-frame-options: SAMEORIGIN
设 IFRAME_EMBED_ALLOWED: 'true' 重建后:
curl -si --max-time 10 http://localhost:8108 | grep -iE 'HTTP/|x-frame'
回显:
HTTP/1.1 200 OK
x-frame-options 头消失,任意站点可嵌入本站(放开前评估点击劫持风险)。
5.4.2 IFRAME_ALLOWED_ORIGINS
嵌入来源白名单(逗号分隔),仅在 IFRAME_EMBED_ALLOWED=true 时有意义。
实测:在 5.4.1 基础上追加 IFRAME_ALLOWED_ORIGINS: 'https://portal.example.com,https://intranet.example.com',重建后:
curl -si --max-time 10 http://localhost:8108 | grep -iE 'HTTP/|content-security'
回显:
HTTP/1.1 200 OK
content-security-policy: frame-ancestors 'self' https://portal.example.com https://intranet.example.com
从「完全放开」收敛为「仅白名单来源 + 同源」,是生产环境推荐姿势(验证后已还原默认)。
5.5 附件与存储类
5.5.1 STORAGE_DRIVER
附件存储驱动,默认 local(落盘数据目录 storage/,路径结构 storage/<工作区ID>/files/<附件ID>/<文件名>)。可选 s3(AWS S3 及 MinIO 等兼容存储,配套 AWS_S3_* 系列变量,含 AWS_S3_FORCE_PATH_STYLE 默认 false)与 azure(配套 AZURE_STORAGE_* 系列)。切换驱动建议迁移期同时保留旧目录数据。
5.5.2 FILE_UPLOAD_SIZE_LIMIT
单文件上传上限,默认 50mb(页面附件等走此限制;文件导入类另有 FILE_IMPORT_SIZE_LIMIT 默认 200mb)。
实测:设 FILE_UPLOAD_SIZE_LIMIT: '1mb' 重建后,通过 POST /api/files/upload(multipart,pageId 字段须放在 file 字段之前)上传 2MB 文件:接口不报错且返回成功,但落盘文件被截断为 1048576 字节(1MB)——超限内容静默丢弃而非整包拒绝:
ls -l /opt/data/quzuo/docmost-0.96.0/storage/*/files/*/bigfile.bin
回显:
-rw-r--r-- 1 yahui yahui 1048576 10月 18 21:56 /opt/data/quzuo/docmost-0.96.0/storage/01a14f42-c55d-7421-8613-c1e172a123a3/files/01a14f4d-20bc-71ac-8429-e0ce03e8eafc/bigfile.bin
同时上传 100KB 小文件则完整落盘(fileSize: 102400)。结论:该限制按 1MB 边界截断保存,业务上务必按实际需求调大,不要依赖它做拒绝式防护;大附件场景建议直接对接对象存储驱动。
5.6 邮件类
5.6.1 MAIL_DRIVER
邮件驱动,默认 log(日志驱动)。实测核对了日志驱动的行为:它把邮件内容打到应用日志,且源码限定仅非生产模式输出——官方部署启动方式带 NODE_ENV=production,因此默认 log 驱动在生产环境下静默丢弃邮件(不报错、不实发)。触发忘记密码接口只回 {"success":true,"status":200},用户收不到邮件。
可选值(启动校验白名单):smtp、postmark。自托管生产必须显式配置 SMTP:
MAIL_DRIVER: 'smtp'
SMTP_HOST: 'smtp.example.com'
SMTP_PORT: '587'
SMTP_USERNAME: 'no-reply@example.com'
SMTP_PASSWORD: '<SMTP密码>'
SMTP_SECURE: 'false' # 587 端口走 STARTTLS 时保持 false
MAIL_FROM_ADDRESS: 'no-reply@example.com'
MAIL_FROM_NAME: 'Docmost'
实测(SMTP 故障路径):设 MAIL_DRIVER: 'smtp'、SMTP_HOST: '127.0.0.1'、SMTP_PORT: '2525'(无服务监听),重建后触发忘记密码:
curl -s -X POST http://localhost:8108/api/auth/forgot-password \
-H 'Content-Type: application/json' -d '{"email":"admin@example.com"}' -w ' HTTP %{http_code}\n'
回显:
{"success":true,"status":200} HTTP 200
接口正常返回(邮件异步发送),但应用日志出现两条关键记录:
"level":"warn","context":"Mail::SmtpDriver","msg":"Failed to send mail to admin@example.com: Error: connect ECONNREFUSED 127.0.0.1:2525"
"level":"error","context":"EmailProcessor","msg":"Error processing send-email job. Reason: connect ECONNREFUSED 127.0.0.1:2525"
结论:邮件经 Redis 队列异步投递,SMTP 故障不影响主服务,排障看日志中的 Mail::SmtpDriver 与 EmailProcessor 上下文。邮件发送依赖已配置的 REDIS_URL 可用。
5.7 数据库与搜索类
5.7.1 SEARCH_DRIVER
搜索引擎驱动,默认 database(PostgreSQL 内置全文检索,零额外依赖)。可选 typesense(需 Typesense 服务),配套 TYPESENSE_URL(源码默认 http://localhost:8108,务必按实际地址设置)与 TYPESENSE_API_KEY。Typesense 驱动为官方文档标注的企业特性,本文未复现。
5.7.2 DATABASE_MAX_POOL
数据库连接池上限,源码默认 10。中小团队默认足够;出现连接池耗尽告警(日志含 too many clients 或超时)时再调大,需同步核对 PostgreSQL 侧 max_connections 余量。
5.8 协作与集成类
- COLLAB_URL:独立协作服务(WebSocket 实时协作)地址;单机 compose 部署协作服务随应用同进程运行,无需设置。仅当把协作层拆分为独立实例扩展时使用(校验规则:合法 http(s) URL)。配套
COLLAB_DISABLE_REDIS(默认false)。 - DRAWIO_URL:Draw.io 图表服务地址,默认指向官方在线服务;内网隔离环境指向自托管 Draw.io(如
http://<内网地址>:8080)。 - GOTENBERG_URL:PDF 导出服务(Gotenberg)地址,默认空。需要 PDF 导出时部署 Gotenberg 并在此指向它。
- AI_DRIVER / AI_VECTOR_DRIVER:企业版 AI 能力(OpenAI/Gemini/Ollama 模型驱动;向量检索默认
pgvector,可换turbopuffer,配套TURBOPUFFER_*变量)。社区版无效。
5.9 遥测与日志类
- DISABLE_TELEMETRY(默认
false):Docmost 生产模式默认每日上报匿名统计(版本号、用户/页面/空间计数;实例 ID 为密钥哈希,不含业务数据)。内网或合规要求环境设为true关闭。 - LOG_HTTP(默认
false):开启后记录每个 HTTP 请求日志,排障时临时打开。 - DEBUG_MODE(默认
false):调试模式,日志级别提升为 debug,问题定位用,长期开启会放大日志量。
六、生产配置模板
综合实测结论的最小生产 environment: 配置(compose 部署,SMTP + 密码化 Redis):
environment:
APP_URL: 'https://wiki.example.com'
APP_SECRET: '<openssl rand -hex 32 生成,≥32 字符>'
DATABASE_URL: 'postgresql://docmost:<强密码>@db:5432/docmost'
REDIS_URL: 'redis://:<Redis密码>@redis:6379'
MAIL_DRIVER: 'smtp'
SMTP_HOST: 'smtp.example.com'
SMTP_PORT: '587'
SMTP_USERNAME: 'no-reply@example.com'
SMTP_PASSWORD: '<SMTP密码>'
MAIL_FROM_ADDRESS: 'no-reply@example.com'
MAIL_FROM_NAME: 'Docmost'
DISABLE_TELEMETRY: 'true'
要点核对清单:APP_URL 与实际访问地址一致;APP_SECRET ≥32 字符且妥善保管;REDIS_URL 带认证;MAIL_DRIVER 显式 smtp(默认 log 在生产不发信);内网嵌入需求用 IFRAME_ALLOWED_ORIGINS 白名单而非全放开;大文件场景核对 FILE_UPLOAD_SIZE_LIMIT(默认 50mb)。
七、常见问题
7.1 启动报 APP_SECRET 校验失败
日志形如 {"minLength":"APP_SECRET must be longer than or equal to 32 characters"}:密钥短于 32 字符,或仍是官方 compose 占位值。用 openssl rand -hex 32 重新生成。注意换密钥后全员登录态失效。
7.2 忘记密码收不到邮件
默认 MAIL_DRIVER=log,而生产模式下日志驱动静默丢弃邮件(不实发)。配置 SMTP 后重试;排查时看日志 Mail::SmtpDriver/EmailProcessor 记录(5.6 节实测样例)。
7.3 超大附件上传后文件损坏/变小
FILE_UPLOAD_SIZE_LIMIT 超限部分被静默截断(5.5 节实测:2MB 文件在 1mb 限制下落盘 1048576 字节)。调大限制或改用对象存储驱动,并核对反代层的 client_max_body_size(Nginx 默认 1m,会先于应用拦下)。
7.4 登录令牌有效期与文档不一致
官方环境变量文档写默认 30 天,实测 0.96.0 默认 90d(令牌解码 exp - iat = 7776000)。需要短会话时显式设 JWT_TOKEN_EXPIRES_IN(如 24h),改动只影响新签发的令牌。
7.5 Redis 启用密码后应用异常
REDIS_URL 密码格式为 redis://:密码@主机:端口(冒号后直接跟密码)。漏写冒号或用 redis://用户名:密码@ 的用户名格式都会认证失败;现象是应用能启动但邮件等异步任务不工作。
7.6 被第三方系统嵌入 iframe 失败
默认 x-frame-options: SAMEORIGIN 拦截跨源嵌入。内网门户集成:IFRAME_EMBED_ALLOWED=true + IFRAME_ALLOWED_ORIGINS=<门户域名>(实测响应头变为 content-security-policy: frame-ancestors 'self' <白名单>);不要只开 IFRAME_EMBED_ALLOWED 而不配白名单。