NodeBB 配置参数详解

逐项实测 NodeBB v4.16.3 双层配置体系:config.json 文件层与 meta.config 数据库层的查看、修改与生效方式,附生产配置模板与站点标题直写不生效等真实排障。

NodeBBNodeBB论坛2026/10/22

NodeBB 配置参数详解

一、环境信息

  • 操作系统:Ubuntu 22.04.5 LTS(x86_64)
  • NodeBB:v4.16.3(2026-10-14 发布的最新稳定版,安装过程见《Ubuntu 22.04 安装 NodeBB 指南》)
  • Node.js:v22.23.4
  • MongoDB:v8.0.34(mongosh 随 mongodb-org 套件一并安装)
  • NodeBB 安装目录:/opt/nodebb,运行用户 nodebb
  • NodeBB 服务端口:4567,站点 URL:http://10.89.68.10:4567
  • NodeBB 已由 systemd 托管(单元名 nodebb.service)
  • 数据库账号:NodeBB 专用账号 nodebb / q1w2e3r4(MongoDB 内建认证);NodeBB 管理员账号 admin / q1w2e3r4
  • 本文所有命令与回显均在上述环境实测,查询日期 2026-10-22

二、前置条件

  1. 已按《Ubuntu 22.04 安装 NodeBB 指南》完成 NodeBB v4.16.3 安装并可通过 http://<服务器IP>:4567 正常访问;
  2. 具备服务器 root 或 sudo 权限(修改 config.json、操作 systemd 需要);
  3. 如需直查数据库层配置,MongoDB 端 mongosh 可用,且持有 NodeBB 数据库账号(安装时创建的 nodebb 账号具备 nodebb 库读写权限,足够);
  4. 了解 NodeBB 管理后台(ACP,Admin Control Panel,http://<服务器IP>:4567/admin)的登录方式,可用管理员账号 admin 登录。

三、参数查看与修改方式

3.1 双层配置结构

NodeBB 的运行配置分布在两层,理解分层是修改参数的前提:

层载体加载时机生效方式典型内容
文件层/opt/nodebb/config.json进程启动时由 nconf 一次性读入必须重启 NodeBB 进程端口、监听地址、数据库连接、TLS 证书、守护化开关
数据库层MongoDB objects 集合中 _key: "config" 的文档启动时读入内存(Meta.config),运行期经 pubsub 同步管理后台修改即时生效;直改数据库需重启站点标题、分页、发帖限制、上传限制等全部功能开关

两层的边界在源码中非常清晰:文件层参数由 config.json 经 nconf 注入,用 nconf.get('xxx') 读取(如 src/webserver.js 中的 port、bind_address、ssl);数据库层参数统一挂在 meta.config 对象上(如 meta.config.title),默认值定义在 install/data/defaults.json(实测共 224 个键),数据库中实际存储的 _key: "config" 文档实测有 232 个字段(多出的部分是管理后台保存时写入的历史键)。

判断一个参数属于哪一层的实用方法:管理后台(ACP)界面上能改的,几乎都在数据库层;./nodebb setup 初始化时填写或与进程运行方式相关的(端口、地址、数据库连接、证书),都在文件层。

3.2 查看文件层配置

直接读文件即可,config.json 是标准 JSON:

cat /opt/nodebb/config.json

实测回显(./nodebb setup 初始化生成的原始内容):

{
    "url": "http://10.89.68.10:4567",
    "secret": "b874fbc6-5562-4c33-adef-591a08beca6c",
    "database": "mongo",
    "mongo": {
        "host": "127.0.0.1",
        "port": "27017",
        "username": "nodebb",
        "password": "q1w2e3r4",
        "database": "nodebb",
        "uri": ""
    },
    "port": "4567"
}

3.3 修改文件层配置与生效方式

文件层修改流程固定三步:编辑 config.json → 校验 JSON 语法 → 重启进程。以临时把端口改为 4568 验证为例:

sudo python3 -c "
import json
p='/opt/nodebb/config.json'
c=json.load(open(p))
c['port']='4568'
json.dump(c,open(p,'w'),indent=4)
"
sudo systemctl restart nodebb
sleep 20

重启后实测:旧端口已无监听,新端口返回 HTTP 200:

$ curl -s -o /dev/null -w '%{http_code}\n' -m 5 http://127.0.0.1:4567
000
$ curl -s -o /dev/null -w '%{http_code}\n' -m 5 http://127.0.0.1:4568
200

注意 url 与 port 是两个独立参数:url 是对外Canonical URL(影响生成的绝对链接、Cookie 作用域),port 才是实际监听端口。只改 port 不改 url 时站点仍可访问,但部分依赖 url 的功能(如邮件中的链接)仍指向旧地址。测试完成后将 port 改回 4567 并重启。

JSON 语法校验建议在重启前执行,语法错误会导致启动失败:

python3 -m json.tool /opt/nodebb/config.json > /dev/null && echo OK

3.4 查看数据库层配置

数据库层配置存储在 MongoDB nodebb 库的 objects 集合中,_key 为 config 的单个文档。用安装 NodeBB 的数据库账号直查(密码即 config.json 中 mongo.password 的值):

mongosh 'mongodb://nodebb:q1w2e3r4@127.0.0.1:27017/nodebb' --quiet \
  --eval 'db.objects.findOne({_key:"config"},{title:1,_id:0})'

实测回显:

{ title: 'NodeBB' }

统计该文档字段数(了解数据库层配置规模):

mongosh 'mongodb://nodebb:q1w2e3r4@127.0.0.1:27017/nodebb' --quiet \
  --eval 'const d=db.objects.findOne({_key:"config"});print("字段数: "+Object.keys(d).length)'

实测回显:

字段数: 232

导出全部数据库层配置备查(排除 _id 与 _key 两个元数据字段):

mongosh 'mongodb://nodebb:q1w2e3r4@127.0.0.1:27017/nodebb' --quiet \
  --eval 'const d=db.objects.findOne({_key:"config"});delete d._id;delete d._key;printjson(d)'

不带投影字段时返回全部键值,逐条打印站点标题、分页等现值,适合变更前备份。

3.5 修改数据库层配置

方式一:管理后台(推荐)。 管理员登录 ACP 后在对应设置页修改并保存,NodeBB 通过 pubsub 将变更即时广播到所有运行中的进程,无需重启。这是官方设计的使用方式。

方式二:直改数据库 + 重启。 适合脚本化批量初始化,但必须理解其生效条件——NodeBB 启动时执行 Meta.configs.init() 从 _key: "config" 文档读入并合并默认值,之后运行期不再回读数据库。因此直改数据库后必须重启 NodeBB 才生效,这一点与管理后台的即时生效截然不同。实测验证见第 6.3 节。

3.6 运行态核对:/api/config

两层配置合并后的对外可见结果,可通过 REST 端点核对(无需认证):

curl -s http://127.0.0.1:4567/api/config | python3 -m json.tool | grep -E '"siteTitle"|"version"'

实测回显:

    "siteTitle": "NodeBB",
    "version": "4.16.3",

该端点返回的是站点对外元信息(含数据库层多数现值),是验证「改动是否真正生效」的最直接观测点。

四、文件层(config.json)参数总览

文件层参数没有官方单独的配置手册页(旧版 docs.nodebb.org 的 config.json 页已下线,实测返回 404),以下键位从 v4.16.3 源码(loader.js、src/webserver.js、src/prestart.js)取证并逐项归类:

参数类型默认值说明
url字符串无(必填)站点对外 Canonical URL,setup 时生成
secret字符串无(setup 自动生成 UUID)会话 Cookie 签名密钥,更换后全体会话失效
database字符串无(必填)数据库类型,仅 mongo / redis / postgres 三选一
mongo.host / mongo.port字符串127.0.0.1 / 27017MongoDB 连接地址
mongo.username / mongo.password / mongo.database字符串—MongoDB 认证信息
mongo.uri字符串空串完整连接串,非空时优先于逐项拼装
port字符串4567HTTP(S) 监听端口
bind_address字符串0.0.0.0(缺省即全网卡)监听地址,见 5.2 实测
ssl.enabled布尔false启用内置 TLS
ssl.cert / ssl.key字符串—证书/私钥路径,fs.readFileSync 直接读取
daemon布尔true(即「非 false 就守护化」)loader.js 自守护化开关,systemd 托管必须显式 false
silent布尔truetrue 时日志只写文件不上抛控制台
logFile字符串logs/output.log日志文件路径(相对安装目录)
max-memory数字未设置映射为 Node --max-old-space-size,限制 V8 堆
trust_proxy布尔/字符串falseExpress trust proxy,置于反代之后时需设置
log-level字符串生产环境 info,否则 verbose日志级别
json-logging布尔falseJSON 结构化日志
log-colorize布尔true控制台日志着色
jobsDisabled布尔false禁用本实例的定时任务(多实例部署时从实例置真)
socket.io.origins数组—WebSocket 允许的来源,跨域访问时需配置
cookie.domain / cookie.secure字符串/布尔—会话 Cookie 作用域与 Secure 标记

「默认值」一列的依据:daemon、silent、max-memory、logFile 取自 loader.js 源码(如 loader.js 第 179 行 if (nconf.get('daemon') !== 'false' && nconf.get('daemon') !== false) 表明只要不是显式 false 就守护化);bind_address、trust_proxy、ssl 取自 src/webserver.js 源码。

五、文件层核心参数逐项实测

5.1 port — 监听端口

默认 4567。修改方法与完整实测见 3.3:改为 4568 并重启后,旧端口 curl 返回 000、新端口返回 200,确认端口切换立即生效。生产中改端口的常见动机是避免与宿主机上其他服务冲突,或配合非特权端口约束(NodeBB 以普通用户运行,监听 1024 以上端口无需特权)。

5.2 bind_address — 监听地址

默认监听 0.0.0.0(全部网卡)。源码逻辑(src/webserver.js):

const bind_address = ((nconf.get('bind_address') === '0.0.0.0' || !nconf.get('bind_address')) ? '0.0.0.0' : nconf.get('bind_address'));

即缺省、空值或显式 0.0.0.0 都监听全网卡。实测在 config.json 中加入 "bind_address": "127.0.0.1" 并重启:

日志回显(启动日志尾部):

... - info: 📡 NodeBB is now listening on: 127.0.0.1:4567

验证监听范围——外部地址连接失败、本机回环正常:

$ curl -s -o /dev/null -w '%{http_code}\n' -m 5 http://10.89.68.10:4567/
000
$ curl -s -o /dev/null -w '%{http_code}\n' -m 5 http://127.0.0.1:4567/
200

适用场景:NodeBB 前面有反向代理(同机 Nginx)时,把 NodeBB 收进回环地址,仅暴露代理端口。实测后已删除该键恢复全网卡监听。

5.3 ssl — 内置 TLS

config.json 支持 NodeBB 进程直接终结 TLS,结构与源码(src/webserver.js 第 60-63 行)一致:

"ssl": {
    "enabled": true,
    "cert": "/etc/nodebb/ssl/nodebb.crt",
    "key": "/etc/nodebb/ssl/nodebb.key"
}

实测用自签证书验证(证书由 openssl req -x509 -newkey rsa:2048 -nodes -days 30 -subj "/CN=10.89.68.10" 现场生成):

$ curl -sk -o /dev/null -w 'HTTPS=%{http_code}\n' -m 5 https://127.0.0.1:4567/
HTTPS=200
$ curl -s -o /dev/null -w 'HTTP=%{http_code}\n' -m 5 http://127.0.0.1:4567/
HTTP=000

启用后 4567 端口只讲 TLS:https:// 返回 200,http:// 得到 000(curl 以退出码 52 报 empty reply)。两点提醒:

  • cert/key 路径由 fs.readFileSync 启动时同步读取,路径不存在或权限不足会直接启动失败;
  • 使用反向代理终结 TLS 的部署(更常见)不要开此项,避免双层加密。

实测后已从 config.json 移除 ssl 块并重启,恢复纯 HTTP。

5.4 daemon / silent / logFile / max-memory — 进程形态四件套

这四个参数都由 loader.js(./nodebb start 实际执行的入口)消费:

  • daemon:loader.js 中只要 daemon 不是显式 false/'false',就调用 daemon 库脱离前台。这是 systemd 托管的最大坑位:单元不加 Environment=daemon=false 时,NodeBB 启动后自行 fork 脱离,systemd 认为主进程退出而反复拉起,形成无限重启。B1 安装实测踩坑与解法详见《Ubuntu 22.04 安装 NodeBB 指南》常见问题一节。
  • silent:默认 true,日志只落 logFile 文件;systemd 场景下希望 journalctl -u nodebb 能看到日志,需要显式 "silent": false。本环境在 nodebb.service 单元中以 Environment="silent=false" 覆盖。
  • logFile:默认 logs/output.log(相对安装目录),排障第一入口:tail -f /opt/nodebb/logs/output.log。
  • max-memory:设置后 loader 以 --max-old-space-size=<值> 拉起子进程,限制 V8 堆上限(单位 MB)。中小站点建议 512-1024,防内存失控。

5.5 trust_proxy — 反向代理信任

未配置时启动日志会给出明确提示(实测日志原文):

2026-10-22T02:43:38.379Z [4567/10514] - warn: [startup] 'trust_proxy' is not configured, so Express proxy trust is disabled by default. Set 'trust_proxy' in config.json only when NodeBB is behind a reverse proxy that strips or overwrites X-Forwarded-For from untrusted clients.
2026-10-22T02:43:38.379Z [4567/10514] - info: ❌ Setting 'trust proxy' to false
2026-10-22T02:43:38.382Z [4567/10514] - info: 📡 NodeBB is now listening on: 0.0.0.0:4567

含义:直连部署保持默认(false)即可,避免客户端伪造 X-Forwarded-For 绕过 IP 限速与封禁;仅当 NodeBB 处于会改写该头的可信反代之后才设 "trust_proxy": true(或填代理网段)。设置后日志前缀从 ❌ 变为 🤝。

5.6 url / secret / database / mongo — 初始化四要素

这四项由 ./nodebb setup 交互生成(实测过程见 B1),日常极少改动:

  • url:Canonical URL。协议、域名、端口都必须与实际访问一致;从 HTTP 迁移到 HTTPS 时必须同步更新,否则出现混合内容与 Cookie 异常;
  • secret:Cookie 签名密钥。更换后所有已登录会话立即失效(签名校验不过),也用于 CSRF 防护令牌派生;
  • database:mongo / redis / postgres 三选一(v4 已无 MySQL 适配层);
  • mongo.*:逐项连接参数;mongo.uri 非空时优先,适合副本集/SRV 等复杂连接串。

六、数据库层(meta.config)参数详解

6.1 总览

数据库层默认值定义于 install/data/defaults.json(实测 224 个键),启动时与 _key: "config" 文档合并进 Meta.config。命名风格两类并存:下划线风格(postsPerPage)与冒号分组风格(email:smtpTransport:pool、min:rep:upvote)。管理后台每一页对应其中一组。

6.2 关键参数默认值表(实测自 defaults.json)

参数默认值说明
title"NodeBB"站点标题(注意:不是 siteTitle,见 6.3)
showSiteTitle1页头是否显示站点标题
minimumPasswordLength6注册/改密最短密码长度
minimumPasswordStrength1zxcvbn 密码强度下限(0-4)
topicsPerPage20主题列表每页条数
postsPerPage20帖子列表每页条数
maximumPostLength32767单帖最大字符数
maximumTitleLength255标题最大字符数
maximumChatMessageLength1000单条聊天消息最大字符数
maximumFileSize2048上传附件上限(KB),即 2MB
postDelay10两次发帖最小间隔(秒)
initialPostDelay10新注册用户首次发帖延迟(秒)
postQueue1新用户发帖先进审核队列
loginAttempts5连续登录失败锁定阈值(配合 lockoutDuration)
sessionDuration0会话时长(天),0 表示跟随浏览器会话
maintenanceMode0维护模式开关
defaultLang"en-GB"默认语言
teaserPost"last-post"主题列表摘要帖(last-post/first/last-reply)
unreadCutoff2未读追踪窗口(天)
onlineCutoff30超过该分钟数无活动记为离线
allowGuestHandles0访客发言是否允许自定义昵称
allowPrivateGroups1允许私密用户组
disableChat0站点级禁用聊天
gdpr_enabled1GDPR 合规提示与同意流程
activitypubEnabled1ActivityPub 联邦(v4 默认开启)
hsts-enabled1HSTS 响应头(需 HTTPS 部署配合)
useCompression0gzip 压缩响应(前置反代已压缩时应关闭)
stripEXIFData1上传图片剥离 EXIF(防位置泄露)

6.3 站点标题:title 键实测与 siteTitle 陷阱

站点标题在数据库层的键是 title。一个容易踩的坑:/api/config 与页面源码里看到的字段名叫 siteTitle,于是直觉上直改数据库里名为 siteTitle 的键——实测这条路不生效。

复现过程:先向 config 文档直写 siteTitle 键并重启,/api/config 的 siteTitle 仍返回 NodeBB。原因在响应构建源码 src/controllers/api.js 第 32 行:

siteTitle: meta.config.title || meta.config.browserTitle || 'NodeBB',

即 siteTitle 是派生字段,取值链为 title → browserTitle → 'NodeBB',根本不读名为 siteTitle 的键。改写正确的 title 键验证:

mongosh 'mongodb://nodebb:q1w2e3r4@127.0.0.1:27017/nodebb' --quiet \
  --eval 'db.objects.updateOne({_key:"config"},{$set:{title:"Quzuo 测试社区"}})'

实测回显:

{
  acknowledged: true,
  insertedId: null,
  matchedCount: 1,
  modifiedCount: 1,
  upsertedCount: 0
}

重启 NodeBB 后核对运行态:

$ curl -s http://127.0.0.1:4567/api/config | grep -o '"siteTitle":"[^"]*"'
"siteTitle":"Quzuo 测试社区"

生效。结论固化:

  1. 直改数据库层任何键后必须重启进程(Meta.config 启动时一次性加载);
  2. 站点标题的正确键名是 title;/api/config 的 siteTitle 是只读派生值;
  3. 管理后台的对应入口是 Settings → General → Site Title,后台保存即时生效,无需重启。

实测后已将 title 还原为 NodeBB(并清理实验写入的 siteTitle 键),复核 "siteTitle":"NodeBB"、HTTP 200。

6.4 安全与账户类参数

  • minimumPasswordStrength:zxcvbn 评分下限,默认 1。B1 安装实测中管理员密码 q1w2e3r4 评分为 0,被 setup 以「Weak password」拒绝,最终将该参数临时置 0 后完成初始化——完整排障过程见《Ubuntu 22.04 安装 NodeBB 指南》。生产建议保持默认或提高至 2,并对已建管理员改用强密码;
  • loginAttempts(默认 5)+ lockoutDuration:登录失败锁定策略;
  • sessionDuration:默认 0(浏览器会话期);对外站点可设 1-14(天)平衡安全与体验;
  • maintenanceMode:置 1 后仅管理员可访问,升级维护窗口使用,访客看到 maintenanceModeStatus 文案。

6.5 内容与反垃圾类参数

  • postDelay / initialPostDelay(默认各 10 秒):限速防灌水,社区初期可适当调低以降低挫败感;
  • postQueue(默认开):新用户首帖进入审核队列,配合 postQueueReputationThreshold(声望达标后免审);
  • minimumPostLength / maximumPostLength / minimumTitleLength / maximumTitleLength:内容长度边界;
  • newbiePostDelay / newbieReputationThreshold:新用户梯度限速。

6.6 上传类参数

  • maximumFileSize(默认 2048 KB):附件上限,改大后注意 PHP 式的层层限制在此不存在,但若有 Nginx 前置,还需同步调整 Nginx 的 client_max_body_size;
  • allowedFileExtensions / blockedFileExtensions:扩展名白/黑名单;
  • privateUploads(默认关):开启后附件需登录访问,防资源盗链与隐私泄露;
  • stripEXIFData(默认开)与 resizeImageWidth:隐私与带宽优化。

七、生产配置模板

7.1 直连部署(无反代,NodeBB 自终结 TLS)

/opt/nodebb/config.json:

{
    "url": "https://forum.example.com",
    "secret": "<setup 自动生成,勿换>",
    "database": "mongo",
    "mongo": {
        "host": "127.0.0.1",
        "port": "27017",
        "username": "nodebb",
        "password": "<强密码>",
        "database": "nodebb",
        "uri": ""
    },
    "port": "4567",
    "bind_address": "127.0.0.1",
    "ssl": {
        "enabled": true,
        "cert": "/etc/nodebb/ssl/fullchain.pem",
        "key": "/etc/nodebb/ssl/privkey.pem"
    },
    "daemon": false,
    "silent": false,
    "max-memory": 1024,
    "trust_proxy": false
}

要点:url 必须与对外 HTTPS 域名严格一致;daemon:false 与 silent:false 是 systemd 托管的固定搭配;max-memory 给 V8 堆设 1GB 上限。

7.2 反向代理部署(Nginx 终结 TLS,推荐)

/opt/nodebb/config.json:

{
    "url": "https://forum.example.com",
    "secret": "<setup 自动生成,勿换>",
    "database": "mongo",
    "mongo": {
        "host": "127.0.0.1",
        "port": "27017",
        "username": "nodebb",
        "password": "<强密码>",
        "database": "nodebb",
        "uri": ""
    },
    "port": "4567",
    "bind_address": "127.0.0.1",
    "daemon": false,
    "silent": false,
    "max-memory": 1024,
    "trust_proxy": true
}

要点:NodeBB 只监听回环(bind_address: "127.0.0.1",5.2 节实测行为),TLS 由 Nginx 终结;trust_proxy: true 使 NodeBB 信任 X-Forwarded-For,IP 限速与封禁功能才能拿到真实客户端 IP。Nginx 侧需同步:client_max_body_size 不小于数据库层 maximumFileSize,并透传 X-Forwarded-Proto。

7.3 数据库层加固清单(管理后台修改,即时生效)

目标参数与建议值
提高密码门槛minimumPasswordLength ≥ 8,minimumPasswordStrength ≥ 2
防灌水postDelay 10-30,postQueue 开,newbiePostDelay 适当调大
附件安全maximumFileSize 按需,allowedFileExtensions 收紧白名单,stripEXIFData 保持开
会话安全sessionDuration 1-14 天,HTTPS 部署下确认 Cookie Secure 标记
维护窗口maintenanceMode 置 1,完成后置 0

八、常见问题

8.1 改了 config.json 不生效

检查三点:JSON 语法是否合法(python3 -m json.tool 校验);是否重启了进程(文件层仅在启动时读取,systemctl restart nodebb);重启后是否等足了启动时间(实测 15-25 秒,过早 curl 会得 000)。另外确认改的是 /opt/nodebb/config.json 而非其他副本。

8.2 直改数据库的键重启后不生效

优先核对键名。数据库层键名与管理后台界面、/api/config 字段名并不总是一致——6.3 节的 title/siteTitle 就是典型:界面与 API 都叫 siteTitle,存储键却是 title。核对方法:install/data/defaults.json 里的键即存储键全集;或用 mongosh 查 _key:"config" 文档确认键是否存在。

8.3 systemd 托管下 NodeBB 无限重启

现象:systemctl status nodebb 反复显示启动后随即退出,状态码 0(SUCCESS)。根因是 loader.js 默认自守护化,与 systemd 的进程托管语义冲突。解法:单元文件加 Environment=daemon=false(或 config.json 显式 "daemon": false),完整单元文件与排障实录见 B1。

8.4 systemd 托管下 ./nodebb status 显示未运行

正常现象,不是故障。./nodebb status 依据自身 pidfile 判断,systemd 直拉 loader.js 时不写该 pidfile。实测回显:


NodeBB is not running
        "./nodebb start" to launch the NodeBB server

以 systemctl status nodebb 与 HTTP 探活为准。

8.5 启动日志出现 trust_proxy 警告

见 5.5 节。直连部署可忽略;反代部署按 7.2 模板设置 "trust_proxy": true 后警告消失(日志前缀 ❌ → 🤝)。

8.6 更换 secret 的影响

secret 是会话 Cookie 与 CSRF 令牌的签名密钥。更换后所有在线用户立即掉线(旧签名失效),邮箱中的已验证状态等不受影响。仅在怀疑密钥泄露时更换,换完即重启。

8.7 管理后台修改与直改数据库的优先级

两者写同一存储(_key:"config" 文档),后写者胜出。管理后台保存即时广播生效;直改数据库需重启。混用时注意:先直改数据库、重启前有人在后台保存过同名参数,则后台值覆盖直改值。

九、参考链接