Coral 9.11.8 配置参数详解

Coral 9.11.8 全部实例级配置参数(环境变量)逐项详解:加载与修改机制、必需/高级/开发三组参数总览、签名密钥、FORCE_SSL、GraphiQL、指标认证、抓取超时、Webhook 方案校验等关键参数的官方默认值与 2026-11-02 生产语义实测佐证,附生产配置模板与 systemd 托管。

CoralCoral评论系统Node.jsMongoDBRedis2026/11/02

Coral 9.11.8 配置参数详解

目标:把 Coral 9.11.8 的全部实例级配置参数(环境变量)逐项讲清:官方默认值、生产语义、改动生效方式,并对最易踩坑的签名密钥、FORCE_SSL、ENABLE_GRAPHIQL、指标认证、Webhook 方案校验等参数给出 2026-11-02 在 production 运行环境上的逐字实测佐证。租户级配置(站点、审核策略、SSO 等)存于数据库、经管理台修改,不在本篇范围。部署过程见 《Coral Docker Compose 部署指南》。

一、环境信息

本篇参数实测基于以下环境(2026-11-02):

  • 操作系统:Ubuntu 22.04 LTS(x86_64)
  • Coral:9.11.8,production 模式,/usr/src/app/server 下 node dist/index.js 启动,systemd 单元 coral-talk 托管,配置经 EnvironmentFile=/etc/coral/coral.env 注入
  • 运行时:Node.js v18.20.8
  • 依赖:MongoDB 8.0.3(mongodb://127.0.0.1:27017/coral)、Redis 7.2.5(redis://127.0.0.1:6379)
  • 监听:Web/GraphQL 127.0.0.1:8138,Prometheus 指标 127.0.0.1:8139(PORT/METRICS_PORT 显式指定值)
  • 演示管理账号:root / q1w2e3r4(邮箱 root@example.com)
  • 取证方式:对运行中服务进程的环境变量转储、HTTP 端点实测、服务结构化日志逐字采集;另启第二实例复现特定参数行为(见各节标注)

二、前置条件

本篇所有「查看/验证」命令假设服务已在跑,最低校验:

curl -s -w '\n/api/version -> %{http_code}\n' http://127.0.0.1:8138/api/version

实测回显(逐字):

{"version":"9.11.8","revision":""}
/api/version -> 200

改参数需要 root 权限编辑 /etc/coral/coral.env 与重启 coral-talk 单元;生成密钥需要 openssl。从零部署见 《Coral Docker Compose 部署指南》第四章。

三、参数加载与修改方式

3.1 唯一的配置载体:环境变量

Coral 没有配置文件。官方文档原文口径:配置项通过环境变量设置——可以 export NODE_ENV=development 这样暴露在 shell 里,或在项目 server/ 目录下放一个 .env 文件(KEY=VALUE 换行分隔)。服务启动时一次性读取,运行期不重读、无热加载。

配置分两层,边界要划清:

层载体例子生效方式
实例级环境变量(本篇)连接串、密钥、端口、开关改文件 + 重启服务
租户级MongoDB + /admin 管理台 / GraphQL API站点、Permitted Domains、审核策略、Webhook 端点、SSO保存即生效,无需重启

3.2 查看当前生效值:转储服务进程环境

systemctl show 只反映单元声明,最可靠的是直接转储进程环境:

tr '\0' '\n' < /proc/$(pgrep -f 'node dist/index.js')/environ | sort

实测回显(输出节选,官方发行版默认运行时参数部分,逐字):

NODE_ENV=production
NODE_OPTIONS=--max-old-space-size=8192 --openssl-legacy-provider --no-experimental-fetch
NODE_VERSION=18.20.8
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PORT=5000
YARN_VERSION=1.22.22

解读:官方发行形态自带三个关键运行时默认——NODE_ENV=production、PORT=5000(注意官方文档写的 PORT 默认 3000 只对源码运行成立)、NODE_OPTIONS=--max-old-space-size=8192 --openssl-legacy-provider --no-experimental-fetch(8GB 堆上限、旧 OpenSSL provider、禁用实验性 fetch)。自托管源码部署应显式复刻这三项,否则与官方发行行为不一致。

3.3 修改参数三步

vi /etc/coral/coral.env          # 改值
systemctl restart coral-talk     # 重启生效(无热加载)

验证生效统一走 HTTP 端点或行为探测,例如改完 METRICS_PORT 后:

curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8139/metrics

实测回显(配了 METRICS_USERNAME/PASSWORD 的环境):

401

各参数对应的验证手段见第五章。

四、参数总览

以下清单与默认值逐项核对自官方 Environment Variables 页(2026-11-02 存档),按官方分组全量列出:

必需配置:

变量官方默认一句话说明
PORT3000(发行运行时 5000)HTTP/WebSocket 监听端口
MONGODB_URImongodb://127.0.0.1:27017/coralMongoDB 连接串
REDIS_URIredis://127.0.0.1:6379Redis 连接串
SIGNING_SECRETkeyboard catJWT 签名密钥,production 禁用默认值

高级配置:

变量官方默认一句话说明
NODE_ENVproduction(发行/pnpm start)production 或 development
REDIS_OPTIONS{}ioredis 连接选项(JSON 串)
SIGNING_ALGORITHMHS256JWT 签名算法(HS/RS/ES 三族)
LOCALEen-US默认语言
LOGGING_LEVELinfofatal/error/warn/info/debug/trace
FORCE_SSLfalse强制 HTTPS 跳转 + HSTS
DISABLE_LIVE_UPDATESfalse全局关闭评论流 WebSocket
DISABLE_LIVE_UPDATES_TIMEOUT2 weeks故事空闲后暂停实时推送的超时(ms 格式)
DISABLE_TENANT_CACHINGfalse关闭租户内存缓存
ENABLE_GRAPHIQLfalse开启 /graphiql 并放宽持久化查询限制
METRICS_USERNAME未设则无认证/metrics Basic Auth 用户名
METRICS_PASSWORD未设则无认证/metrics Basic Auth 密码
METRICS_PORT9000Prometheus 指标端口
SCRAPE_TIMEOUT10 seconds故事抓取请求超时(ms 格式)
SCRAPE_MAX_RESPONSE_SIZE10e6抓取响应大小上限(字节)
STATIC_URI未设(禁用)静态资源独立分发地址
TRUST_PROXY未设Express "trust proxy",反代场景必配
WEBSOCKET_KEEP_ALIVE_TIMEOUT30sWebSocket 保活间隔
WORD_LIST_TIMEOUT100ms词表匹配请求超时
PERSPECTIVE_TIMEOUT800msPerspective API 请求超时

仅 NODE_ENV=development 生效:

变量官方默认一句话说明
DEV_PORT8080Webpack 开发服务器端口
DISABLE_RATE_LIMITERSfalse关闭内置限流(生产严禁开)

解读:真正「不配就跑不起来」的只有 MONGODB_URI/REDIS_URI(非默认地址时)与 SIGNING_SECRET(production 必配);其余全部有可用默认。按功能域分组逐项详解与实测见第五章,生产取值模板见第六章。

💡 技术拓展:SIGNING_ALGORITHM 可选算法不止 HS256——

族算法密钥形态适用
HMAC 对称HS256/384/512单一共享密钥(SIGNING_SECRET)自签自验的单体部署(默认,本文环境采用)
RSA 非对称RS256/384/512私钥签、公钥验第三方需独立验签、不共享密钥
ECDSA 非对称ES256/384/512同上,密钥更短移动端/高吞吐验签

Coral 单实例自用选默认 HS256 即可;只有「外部系统要自行验 JWT 但不该拿到签名密钥」时才需要 RS/ES。

五、核心参数分类详解

5.1 连接与监听:PORT / MONGODB_URI / REDIS_URI / REDIS_OPTIONS

  • PORT:见 3.2——文档默认 3000,官方发行运行时默认 5000。服务就绪的实测判据是启动日志(逐字):
{"name":"coral","hostname":"13a177526b8d","pid":1,"level":30,"port":5000,"msg":"now listening","time":"2026-11-02T03:21:54.588Z","src":{"file":"/usr/src/app/server/src/core/server/index.ts","line":482,"func":"start"},"v":0}
  • MONGODB_URI:全部业务数据所在。连接成功的实测判据(逐字):
{"name":"coral","hostname":"13a177526b8d","pid":1,"level":30,"msg":"mongodb has connected","time":"2026-11-02T03:21:52.544Z","src":{"file":"/usr/src/app/server/src/core/server/services/mongodb/index.ts","line":58,"func":"createMongoDB"},"v":0}
  • REDIS_URI / REDIS_OPTIONS:Redis 承担事件广播、限流计数、任务队列。连接异常时日志会反复出现 Redis error listener 告警(实测噪音,见 7.8)。REDIS_OPTIONS 是 JSON 串,例:{"maxRetriesPerRequest":null} 用于接入哨兵/集群场景,单体默认 {} 即可。
  • STATIC_URI:把静态资源指到 CDN/反代上游,默认禁用;小站点不需要。
  • TRUST_PROXY:值按 Express 文档(如 1、loopback、网段列表)。反代后管理台 URL 显示 http、或出现重定向环,就是该配它(官方排障口径,实测案例见 7.3)。

5.2 签名密钥:SIGNING_SECRET / SIGNING_ALGORITHM

SIGNING_SECRET 是整个实例的信任根:管理员/读者会话 JWT、API 持久令牌、SSO 令牌全部由它签发(Webhook 端点另有独立 signing secret,见 5.10)。官方文档明示默认值 keyboard cat 仅为开发便利,且:

"Coral will throw a runtime error in the event it's started with NODE_ENV=production and the SIGNING_SECRET="keyboard cat" to prevent insecure installations."

production + 默认值的实测启动失败(逐字日志):

{"name":"coral","hostname":"731abaca4620","pid":1,"level":50,"err":{"message":"SIGNING_SECRET is required in production environments","name":"Error","stack":"new Server (src/core/server/index.ts:156:15)\ncreateCoral (src/core/index.ts:9:10)\nbootstrap (src/index.ts:59:31)\nObject.<anonymous> (src/index.ts:75:1)\n"},"msg":"can not bootstrap server","time":"2026-11-02T03:36:43.294Z","src":{"file":"/usr/src/app/server/src/index.ts","line":70,"func":"bootstrap"},"v":0}

生成与落位(官方推荐 openssl,45 或 48 字节均可,实测用 48 → 64 字符 base64):

openssl rand -base64 48
# 写入 /etc/coral/coral.env: SIGNING_SECRET=<输出值>

密钥值本身属敏感信息,不进文档、不进版本库。换密钥 = 全部会话与 API 令牌立即失效,读者需重新登录,属高影响操作。

5.3 运行模式与日志:NODE_ENV / LOGGING_LEVEL / LOCALE

  • NODE_ENV 不只是性能开关,它改变行为:production 下启用签名密钥护栏(5.2)、Webhook 端点强制 https(5.10)、GraphiQL 放宽伴随告警(5.6)。dev 实例实测 /api/version -> 200 正常但语义宽松。
  • LOGGING_LEVEL 默认 info 已覆盖本篇引用的全部日志(均为 level:30/40/50 输出);排联调可临时 debug。
  • LOCALE 默认 en-US;管理台界面语言,与评论流多语言由租户配置决定。

5.4 HTTPS 与反代:FORCE_SSL / TRUST_PROXY

FORCE_SSL=true 第二实例实测(逐字):

GET /admin -> 301 redirect=https://127.0.0.1:8141/admin
HTTP/1.1 301 Moved Permanently
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
X-XSS-Protection: 1; mode=block
Strict-Transport-Security: max-age=15552000
Location: https://127.0.0.1:8141/admin
Vary: Accept
Content-Type: text/plain; charset=utf-8
Content-Length: 62
Date: Mon, 02 Nov 2026 03:38:00 GMT
Connection: keep-alive
Keep-Alive: timeout=5

三个实测结论:

  1. 它只做 301 跳转 + HSTS 头,不提供证书——直连 https://127.0.0.1:8141 返回 HTTP/1.1 403 Forbidden(实测),TLS 必须由前置反代(Caddy/Nginx)终结;
  2. HSTS max-age=15552000 秒 = 180 天。官方文档写的是 60 天,以实测为准:开启前确保 HTTPS 能稳定供给至少半年,否则浏览器拒绝降级、站点表现为不可达;
  3. 默认 false 时启动即提示(逐字):"FORCE_SSL=true should be set when a SSL terminating proxy has been configured"——前置反代终结 TLS 的部署应显式开 FORCE_SSL=true 并配 TRUST_PROXY(重定向环排障见 7.3)。

5.5 GraphQL 调试开关:ENABLE_GRAPHIQL

该开关同时控制两件事:/graphiql 交互调试台,以及是否放宽「只允许持久化查询白名单」的安全限制。

  • 开启时 production 启动即告警(逐字):
{"name":"coral","hostname":"13a177526b8d","pid":1,"level":40,"msg":"it is not recommended to have enable_graphiql enabled while in production mode as it requires introspection queries to be enabled","time":"2026-11-02T03:21:54.518Z","src":{"file":"/usr/src/app/server/src/core/server/app/router/index.ts","line":78,"func":"attachGraphiQL"},"v":0}
  • 关闭时(第二实例 ENABLE_GRAPHIQL=false 实测):/graphiql -> 404;且未走白名单的原始查询被拒(逐字):
{"error":{"id":"b57dc060-d66e-11f1-adad-d3d6510464fa","traceID":"b57d9950-d66e-11f1-adad-d3d6510464fa","code":"RAW_QUERY_NOT_AUTHORIZED","type":"INVALID_REQUEST_ERROR","message":"You are not authorized to execute this query."},"report":null}
  • 同一原始查询在开启实例上直接成功(逐字):
{"data":{"sites":{"nodes":[{"name":"demo-site"}]}}}
  • 服务启动会加载 236 条持久化查询(逐字 "queries":236,"msg":"loaded persisted queries"),这是前端自身的工作机制;外部集成不受影响——以管理员 API 令牌调用即可(见 《Coral 9.11.8 API 使用详解》)。

生产建议:保持默认 false。调试期临时开,用完关闭重启。

5.6 指标端点:METRICS_PORT / METRICS_USERNAME / METRICS_PASSWORD

METRICS_PORT 默认 9000(本文环境设 8139)。配了用户名/密码时启动日志出现(逐字)"adding authentication to metrics endpoint",未配则 /metrics 无任何认证裸奔。实测对照:

curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8139/metrics
curl -s -u admin:q1w2e3r4 http://127.0.0.1:8139/metrics | head -8

实测回显(输出节选,实测首尾):

401
# HELP process_cpu_user_seconds_total Total user CPU time spent in seconds.
# TYPE process_cpu_user_seconds_total counter
process_cpu_user_seconds_total 3.60966

# HELP coral_executed_graph_queries_total number of GraphQL queries executed
# HELP coral_executed_graph_queries_timings timings for execution times of GraphQL operations
# HELP coral_connected_websockets_total number of websocket connections being handled
coral_executed_graph_queries_total{operation_type="mutation",operation_name="CreateTokenMutation"} 2

Coral 专属指标三个:coral_executed_graph_queries_total(按操作名计数)、coral_executed_graph_queries_timings(耗时直方图,桶 0.1/5/15/50/100 秒)、coral_connected_websockets_total(WS 连接数)。生产必配 Basic Auth 且指标端口不要暴露公网。

5.7 实时与 WebSocket:DISABLE_LIVE_UPDATES / DISABLE_LIVE_UPDATES_TIMEOUT / WEBSOCKET_KEEP_ALIVE_TIMEOUT

  • DISABLE_LIVE_UPDATES=true 全局关闭评论流 WebSocket,且关闭后无法从界面再打开(官方口径),属逃生阀;
  • DISABLE_LIVE_UPDATES_TIMEOUT 默认 2 weeks:故事空闲超时自动暂停实时推送,来了新评论再恢复(ms 格式解析,如 1 day);
  • WEBSOCKET_KEEP_ALIVE_TIMEOUT 默认 30s:保活心跳间隔,反代空闲超时小于它时会看到断连重连,调反代而不是调它。

5.8 抓取与外部调用超时:SCRAPE_* / WORD_LIST_TIMEOUT / PERSPECTIVE_TIMEOUT

  • SCRAPE_TIMEOUT(默认 10 seconds)与 SCRAPE_MAX_RESPONSE_SIZE(默认 10e6 字节)管故事元数据抓取:付费墙/非 200 响应抓不到标题时,管理台显示 "Not available",可在 Actions 里 Re-scrape,或用 API 的 debugScrapeStoryMetadata 查询定位(D5 篇);
  • WORD_LIST_TIMEOUT 默认 100ms、PERSPECTIVE_TIMEOUT 默认 800ms:评论过审时对外部检测的单次请求上限,超时按放行/降级处理,高并发站点可适当收紧以免拖慢发帖。

5.9 租户缓存:DISABLE_TENANT_CACHING

默认 false:租户配置常驻内存、经 Redis pub/sub 广播失效同步(a tenant has been installed 等事件即走该机制)。设 true 后每次查库——只在调试租户配置不生效这类问题时用,生产保持默认。

5.10 Webhook 方案校验(NODE_ENV 联动的隐性约束)

production 下创建 http:// 端点的 Webhook 会被拒,GraphQL 层只报 INTERNAL_ERROR(逐字):

{"errors":[{"message":"Internal Error","locations":[{"line":1,"column":12}],"path":["createWebhookEndpoint"],"extensions":{"code":"INTERNAL_ERROR","id":"f75167d0-d66e-11f1-8984-e9eacc17974c","traceID":"f74f9310-d66e-11f1-8984-e9eacc17974c","type":"INVALID_REQUEST_ERROR","message":"Internal Error"}}],"data":null}

真实原因在服务日志的 originalError(逐字):

"originalError":{"message":"invalid scheme provided in production: http:","name":"Error","stack":"validateWebhookEndpointInput (src/core/server/services/tenant/webhookEndpoints.ts:35:11)\ncreateWebhookEndpoint (src/core/server/services/tenant/webhookEndpoints.ts:54:3)\n

NODE_ENV=development 实例实测允许 http 且推送成功(HMAC 验签通过,逐条实测见 《Coral 9.11.8 API 使用详解》)。排障要点:GraphQL 报 INTERNAL_ERROR 时翻服务日志找 originalError。

5.11 仅开发模式:DEV_PORT / DISABLE_RATE_LIMITERS

NODE_ENV=development 下才有意义:DEV_PORT(默认 8080,Webpack 开发服务器)与 DISABLE_RATE_LIMITERS(默认 false)。后者生产环境严禁开启——限流器保护着登录、安装、发帖等端点(安装接口 10 秒 1 次即其效果,见 7.7)。

六、生产配置模板

适用场景:16GB 内存、NVMe SSD、单节点新闻站点评论区(MongoDB/Redis 与应用同机;更大流量时把 Mongo 独立出去)。

/etc/coral/coral.env:

NODE_ENV=production
PORT=5000
MONGODB_URI=mongodb://127.0.0.1:27017/coral
REDIS_URI=redis://127.0.0.1:6379
SIGNING_SECRET=<openssl rand -base64 48 生成,勿复用示例>
LOGGING_LEVEL=info
FORCE_SSL=true
TRUST_PROXY=loopback
METRICS_PORT=9000
METRICS_USERNAME=admin
METRICS_PASSWORD=<独立强口令,勿用示例值>
NODE_OPTIONS=--max-old-space-size=8192 --openssl-legacy-provider --no-experimental-fetch

逐项要点:PORT=5000 对齐官方发行运行时(3.2 实测),前置 Nginx/Caddy 反代到它;FORCE_SSL=true + TRUST_PROXY=loopback 是「同机反代终结 TLS」的标准组合(HSTS 180 天承诺见 5.4,上 HTTPS 稳定后再开);不设 ENABLE_GRAPHIQL(生产保持默认 false,5.5);NODE_OPTIONS 复刻官方运行时(3.2 实测转储)。

systemd 单元 /etc/systemd/system/coral-talk.service:

[Unit]
Description=Coral Comment Platform
After=network.target mongod.service redis-server.service

[Service]
Type=simple
User=coral
WorkingDirectory=/usr/src/app/server
EnvironmentFile=/etc/coral/coral.env
ExecStart=/usr/bin/node dist/index.js
Restart=always

[Install]
WantedBy=multi-user.target

⚠️ 注意:User=coral 降权运行对齐官方发行形态(其进程以非特权用户启动,3.2 环境转储可证);NODE_OPTIONS 里堆上限按机器内存调,16GB 机器给 8192 与官方默认一致。

改配置后的验证闭环(实测命令与回显):

systemctl restart coral-talk
curl -s http://127.0.0.1:5000/api/version
curl -s http://127.0.0.1:5000/api/health
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:9000/metrics

预期:{"version":"9.11.8","revision":""}、OK、401(三项均已在等价环境逐字实测,见第二、5.6 章)。

七、常见问题

7.1 production 启动即退:SIGNING_SECRET is required in production environments

默认值 keyboard cat 触发官方安全护栏,逐字日志与解决见 5.2。

7.2 版本端点 /api/v1 返回 500

实测(逐字):/api/v1 -> 500,而 /api/version -> 200 返回 {"version":"9.11.8","revision":""}。官方 Troubleshooting 页写明 /api/v1 只对 4.x 有效、5.x 起用 /api/version;9.x 沿用后者。探活/监控用 /api/health(返回 OK)或 /api/version。

7.3 反代后管理台重定向环 / URL 显示 http

官方口径:配 TRUST_PROXY(值参照 Express trust proxy 文档,同机反代用 loopback)。若同时开了 FORCE_SSL,跳转目标协议由反代头决定,未配 TRUST_PROXY 时服务把请求当 http、再 301 回 https,形成环。

7.4 Webhook 创建报 INTERNAL_ERROR

GraphQL 错误被包装,真因看服务日志 originalError:production 拒绝 http 端点(invalid scheme provided in production: http:,逐字见 5.10)。接收端上 TLS,或在内网验证场景用 dev 实例。

7.5 原始 GraphQL 查询报 RAW_QUERY_NOT_AUTHORIZED

ENABLE_GRAPHIQL=false(生产默认)时,非白名单原始查询即被拒(逐字见 5.5)。集成方两条路:带管理员 API 令牌调用(令牌不依赖 GraphiQL 开关,见 《Coral 9.11.8 API 使用详解》),或调试期临时开 ENABLE_GRAPHIQL=true(接受 5.5 的告警与风险)。

7.6 /metrics 返回 401

METRICS_USERNAME 与 METRICS_PASSWORD 同时设置才会加认证(只设一个等于没设,官方口径)。采集端配 Basic Auth;实测 401→带凭证 200 对照见 5.6。

7.7 安装/登录接口偶发被限流

内置限流按 IP:安装 check 10 秒 2 次、install 10 秒 1 次;登录失败过多的用户锁定 10 分钟(官方 FAQ 口径)。DISABLE_RATE_LIMITERS 仅 dev 可用,生产不要关。

7.8 日志噪音两条

(node:1) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 12 error listeners added to [Redis] 与 failed to set logging project id Error: Unable to detect a Project Id 在正常实例上持续出现(实测逐字),前者是 Node 对 Redis 多监听器的告警、后者是未接 Google Cloud 的探测失败,均无害;嫌吵可 LOGGING_LEVEL=warn 以下过滤 info,但 error 级噪音无法配置消除。

八、参考链接

Coral 9.11.8 配置参数详解 - Quzuo