4ga Boards 3.3.13 配置参数详解

4ga Boards v3.3.13 全量配置参数详解:必填三项(BASE_URL/DATABASE_URL/SECRET_KEY)与运行、限流、首建、上传、导入、图像、日志、SSO、通知九组变量源码实查默认值,令牌 365 天/登录限流 5 次/日志级别过滤真实实测,附生产模板与常见问题(2026-10-22 实测)。

4ga Boards看板项目管理2026/10/23

4ga Boards 3.3.13 配置参数详解

目标:系统梳理 4ga Boards v3.3.13 服务端的全部配置参数——必填项、默认值、取值约束、生效方式,并对关键参数(令牌有效期、登录限流、日志级别、初始管理员)给出真实行为实测。参数定义均实查自 v3.3.13 源码 server/config/ 与 server/db/seeds/default.js(2026-10-22),实测回显采集自 Docker Compose 栈(见 《4ga Boards 3.3.13 Docker Compose 部署指南》)。组件背景与安装方式见 《4ga Boards 3.3.13 介绍与选型指南》 与 《Ubuntu 22.04 安装 4ga Boards 3.3.13 指南》。

一、环境信息

本文参数实查与实测环境:

  • 实查对象:4ga Boards v3.3.13 官方源码(commit bff02e86954db545c0bb5835bbdea7cdf7740695,tag v3.3.13),重点文件:
    • server/config/custom.js(应用自定义配置中枢,绝大多数参数在此读取)
    • server/config/env/production.js(生产模式 Sails 配置:BASE_URL 决定 WebSocket 合法 origin、TRUST_PROXY、日志器挂载)
    • server/config/session.js(SECRET_KEY → session secret,同时是 JWT 签名密钥)
    • server/config/datastores.js 与 server/db/knexfile.js(DATABASE_URL)
    • server/config/notifications.js(通知服务四件套)
    • server/utils/logger.js(LOG_LEVEL 默认值与日志格式)
    • server/db/seeds/default.js(DEFAULT_ADMIN_* 与 DEFAULT_* 注册类参数,仅首次建库生效)
  • 实测环境:Ubuntu 22.04 宿主机上的 Docker 29.8.1 + Compose v5.5.1,运行 4ga Boards 3.3.13 官方镜像(应用监听 1337,宿主映射 8132)+ PostgreSQL 18 + Redis 8;查询日期 2026-10-22。
  • 版本说明:v3.3.13 为官方最新稳定版(GitHub Releases,2026-07-15 发布),本文全部默认值以该版本源码为准。

二、前置条件

阅读与验证本文参数需要:

  1. 一套已运行的 4ga Boards v3.3.13 实例。没有现成实例时:
  2. 已知 PostgreSQL 连接串与实例对外访问地址(两者是必填参数,见第五章)。
  3. 修改参数需要重启应用进程才能生效(Docker 方式重建容器,systemd 方式 systemctl restart)。

三、参数查看与修改方式

3.1 参数的读取优先级

4ga Boards 服务端配置只有一层环境变量:启动时从进程环境读取(process.env.*),没有独立配置文件解析器。两种主流注入方式:

部署方式注入位置生效方式
官方镜像 + Composedocker-compose.yml 的 environment: 段(或 docker compose up 时的 shell 环境变量)docker compose up -d 重建应用容器
官方镜像 + docker rundocker run -e VAR=value ...重新 docker run
源码手动安装源码目录 server/.env(服务端入口通过 dotenv 加载)systemctl restart 或重启 start.sh

⚠️ 注意:v3.3.13 源码中 process.env.X || 默认值 是唯一默认值机制,.env 文件里的值与 Compose environment: 没有优先级合并问题——镜像版不读 .env(文件不在镜像工作目录),源码版只读 server/.env。同一实例只会有一种注入源。

3.2 查看当前生效值

Docker 方式直接查看容器进程环境:

docker exec <应用容器名> sh -c 'env | grep -E "^(BASE_URL|DATABASE_URL|TOKEN_EXPIRES_IN|LOG_LEVEL)=" '

输入(本文实测栈,应用容器名 4ga-boards-3313-stack-4gaBoards-1):

docker exec 4ga-boards-3313-stack-4gaBoards-1 sh -c 'env | grep -E "^(BASE_URL|DATABASE_URL|TOKEN_EXPIRES_IN|LOG_LEVEL)="'

输出:

BASE_URL=http://localhost:8132
DATABASE_URL=postgresql://postgres:q1w2e3r4@db/4gaBoards
TOKEN_EXPIRES_IN=365

说明:LOG_LEVEL 未出现在输出中,表示该实例未显式设置此变量,此时默认值 warn(生产模式)在代码中生效——「未设置」与「设置为默认值」等效。

源码方式查看 server/.env 即可:

grep -E '^[A-Z]' /opt/4gaBoards/src/server/.env

3.3 修改参数与生效验证

以修改令牌有效期为 30 天(Docker Compose 方式)为例:

  1. 编辑 docker-compose.yml,在应用服务 environment: 段加一行 TOKEN_EXPIRES_IN: 30;
  2. 重建应用容器:docker compose up -d(只有应用服务配置变化时会重建应用容器);
  3. 重新登录获取新令牌并验证(验证方法见第六章 6.3 节实测)。

源码方式:编辑 /opt/4gaBoards/src/server/.env 后 systemctl restart 4gaboards。

⚠️ 重要:DEFAULT_ADMIN_*、DEFAULT_*REGISTRATION* 等「首建类」参数只在数据库首次初始化时读取(见 6.4 节),对已有数据库永远不会重新生效;其余「运行类」参数每次重启都会重新读取。

四、参数总览

下表按功能分组列出 v3.3.13 全部环境变量参数(默认值实查自源码;「—」表示无默认值)。详细行为与实测见第五章。

4.1 必填参数(生产环境缺失无法运行)

变量默认值作用
BASE_URL—(缺失启动即崩)对外访问地址;决定 WebSocket 合法 origin、附件/头像/SSO 回调等全部 URL
DATABASE_URL—(缺失启动即崩)PostgreSQL 连接串,如 postgresql://用户:密码@主机:5432/库名
SECRET_KEY—(缺失令牌不可用)session secret 与 JWT 签名密钥;更换后全部已登录令牌失效

4.2 基础运行

变量默认值作用
NODE_ENV(开发模式行为)生产部署必须 production;影响日志默认级别与格式、通知定时任务节奏
PORT1337HTTP 监听端口(Sails 默认,亦可用 --port 参数覆盖)
TZ宿主/容器时区日志时间戳时区(源码版建议显式设置)
TRUST_PROXY未设(false)反向代理场景设任意非空值(如 1),使 X-Forwarded-* 生效,客户端 IP 取真实 IP
CLIENT_URL生产=BASE_URL;开发=http://localhost:3000前端访问地址(前后端分离部署时单独指定)
INSTANCE_NAME4gaboards.com实例名称(可观测性与部分对外标识用)

4.3 认证与登录限流

变量默认值作用
TOKEN_EXPIRES_IN365登录令牌有效期,单位天(非数字时回退 365)
AUTH_RATE_LIMIT_ENABLEDtrue登录限流总开关(仅显式 false 关闭)
AUTH_RATE_LIMIT_MAX_ATTEMPTS5窗口内允许的失败尝试次数(最小 1)
AUTH_RATE_LIMIT_WINDOW_MS60000限流窗口毫秒数(代码强制下限 60000,设更小值无效)

4.4 首建类参数(仅数据库首次初始化时生效)

变量默认值作用
DEFAULT_ADMIN_USERNAMEdemo初始管理员用户名
DEFAULT_ADMIN_EMAILdemo@demo.demo初始管理员邮箱
DEFAULT_ADMIN_NAMEDemo Demo初始管理员显示名
DEFAULT_ADMIN_PASSWORDdemo初始管理员密码
DEFAULT_REGISTRATION_ENABLEDtrue开放注册总开关(显式 false 关闭)
DEFAULT_LOCAL_REGISTRATION_ENABLEDtrue本地账号注册开关
DEFAULT_SSO_REGISTRATION_ENABLEDtrueSSO 注册开关
DEFAULT_PROJECT_CREATION_ALLtrue所有用户可建项目开关(false 仅管理员可建)
DEFAULT_SYNC_SSO_DATA_ON_AUTHfalse登录时同步 SSO 资料(显式 true 开启)
DEFAULT_SYNC_SSO_ADMIN_ON_AUTHfalse登录时同步 SSO 管理员身份(显式 true 开启)
DEFAULT_ALLOWED_REGISTER_DOMAINS空(不限制)注册邮箱域名白名单,分号分隔,如 a.com;b.com

4.5 上传限流

变量默认值作用
UPLOAD_RATE_LIMIT_ENABLEDtrue上传限流总开关(仅显式 false 关闭)
UPLOAD_RATE_LIMIT_MAX_ATTEMPTS30窗口内允许的上传请求数(最小 1)
UPLOAD_RATE_LIMIT_WINDOW_MS60000上传限流窗口毫秒数(下限 1000)
UPLOAD_RATE_LIMIT_STOREmemory计数存储:memory(单实例)或 redis(多实例共享)
UPLOAD_RATE_LIMIT_REDIS_URL—(store=redis 时必填)Redis 连接串,如 redis://:密码@redis:6379/0
UPLOAD_RATE_LIMIT_REDIS_CONNECT_TIMEOUT_MS500Redis 连接超时毫秒(下限 100)
UPLOAD_RATE_LIMIT_KEY_PREFIXrl:uploadRedis 计数键前缀(多实例隔离时修改)

4.6 文件大小上限(单位:字节)

变量默认值作用
ATTACHMENT_MAX_BYTES26214400(25 MiB)单个附件上传上限
AVATAR_MAX_BYTES26214400(25 MiB)用户头像上传上限
PROJECT_BACKGROUND_IMAGE_MAX_BYTES26214400(25 MiB)项目背景图上传上限
BOARD_IMPORT_MAX_BYTES104857600(100 MiB)看板导入压缩包上限
BOARD_IMPORT_MAX_COMPRESSED_BYTES104857600(100 MiB)导入包内单个压缩文件上限
BOARD_IMPORT_MAX_UNCOMPRESSED_BYTES524288000(500 MiB)导入包解压后总量上限
BOARD_IMPORT_MAX_ENTRIES5000导入包内条目数上限
BOARD_IMPORT_MAX_EXTRACTION_MS30000解压耗时上限毫秒(下限 1000)

4.7 图像处理(sharp)

变量默认值作用
SHARP_MAX_INPUT_PIXELS40000000单张图片最大输入像素数
SHARP_CONCURRENCY2图像处理并发线程数
SHARP_CACHE_MEMORY_MB50图像缓存内存 MB
SHARP_CACHE_ITEMS100图像缓存条目数
SHARP_CACHE_FILES20图像缓存文件数

4.8 日志

变量默认值作用
LOG_LEVEL生产 warn;非生产 info应用日志最低输出级别(winston:error/warn/info/verbose/silly)

4.9 单点登录(SSO,四组变量各自齐备后自动启用)

变量作用
GOOGLE_CLIENT_ID + GOOGLE_CLIENT_SECRETGoogle 登录(两者齐备启用)
GITHUB_CLIENT_ID + GITHUB_CLIENT_SECRETGitHub 登录(两者齐备启用)
MICROSOFT_CLIENT_ID + MICROSOFT_CLIENT_SECRETMicrosoft 登录(两者齐备启用)
OIDC_CLIENT_ID + OIDC_CLIENT_SECRET + OIDC_STATE_SECRET + (OIDC_AUTH_URL+OIDC_TOKEN_URL+OIDC_USERINFO_URL 或 OIDC_ISSUER_URL)通用 OIDC 登录:六个授权端点变量齐备启用;仅提供 OIDC_ISSUER_URL 时自动推导三个端点
OIDC_ENABLED_METHODS启用的 OIDC 登录方式 hint,逗号分隔
OIDC_DISABLE_HINT_<METHOD>设 true 禁用单个 OIDC 方式(如 OIDC_DISABLE_HINT_GOOGLE)
OIDC_SKIP_ACCOUNT_SELECTION / OIDC_SKIP_ACCOUNT_SELECTION_HINT_<METHOD>设 true 跳过账号选择页(Microsoft 方式对应 prompt=login)

SSO 回调地址由 BASE_URL 自动推导:<BASE_URL>/auth/google、<BASE_URL>/auth/github、<BASE_URL>/auth/microsoft、<BASE_URL>/auth/oidc,在 IdP 侧登记回调时须与此一致。

4.10 通知与可观测性

变量默认值作用
NOTIFICATIONS_HOST_URL生产固定 https://notifications.4gaboards.com官方通知服务地址(与下三项齐备才启用通知服务)
NOTIFICATIONS_CLIENT_ID / NOTIFICATIONS_CLIENT_SECRET—官方通知服务凭据
MAIL_SERVICE_INBOUND_EMAIL—官方邮件服务入站邮箱
SYSTEM_NOTIFICATIONS_DISABLEDfalse显式 true 关闭系统通知(离线/内网部署建议关闭)
DEMO_MODEfalse显式 true 开启演示模式
METRICS_ENABLEDfalse显式 true 开启指标端点
HYPERDX_ENABLED / HYPERDX_API_KEY / HYPERDX_INSTANCE_NAME / HYPERDX_TRACE_PROPAGATION_TARGETS—HyperDX 可观测性接入
OTEL_URL / OTEL_URL_FORMAT— / http/protobufOpenTelemetry 上报地址与格式
ANDROID_PACKAGE_NAME / ANDROID_SHA256_FINGERPRINTcom.ga4boards.app / 官方指纹移动端 App 校验信息(自签名分发时修改)

另有一组硬编码常量(非环境变量,改配置无法调整):看板位置间隔 positionGap=65535、密码强度要求 requiredPasswordStrength=2、列表缓存 cacheMaxAge=900 秒、动作/评论分页 actionsLimit=commentsLimit=50。

五、必填参数详解

5.1 BASE_URL——一切 URL 的基准

BASE_URL 是整个实例的对外地址(含协议、域名/IP、端口),生产配置下被 5 处直接消费(源码 config/env/production.js、config/custom.js):

  1. WebSocket 合法 origin:onlyAllowOrigins: [new url.URL(process.env.BASE_URL).origin]——浏览器 WebSocket 握手 origin 与其不符会被拒绝(前端页面能打开但实时更新失效的典型根因);
  2. 附件、头像、项目背景图、看板导出的访问 URL 前缀;
  3. 四组 SSO 回调地址基准;
  4. CLIENT_URL 未显式设置时的前端地址。

实测验证:本文实测栈 BASE_URL=http://localhost:8132,登录接口返回的令牌可正常建立 WebSocket(实时卡片更新正常);若改为 http://127.0.0.1:8132 访问同一实例,浏览器 origin 变为 http://127.0.0.1:8132,与配置的 localhost origin 不匹配,实时更新将静默失败。生产对外域名一经使用不宜再改(附件 URL 已按旧域名写入库中记录)。

⚠️ BASE_URL 缺失时生产模式启动直接抛 TypeError(new url.URL(undefined)),进程退出——这也是「容器起来又立刻退出」排障的第一检查项。

5.2 DATABASE_URL——数据库连接串

标准格式 postgresql://用户:密码@主机:5432/库名。被服务端(config/datastores.js)与迁移/初始化脚本(db/knexfile.js)同时读取,两者必须一致。实测栈取值:

DATABASE_URL=postgresql://postgres:q1w2e3r4@db/4gaBoards

排障参考(B2 部署指南 FAQ 同源问题):主机名错或 PostgreSQL 未就绪时报 ECONNREFUSED 5432;密码错报 password authentication failed for user。PostgreSQL 侧密码仅在数据目录首次初始化时生效,后续改环境变量不生效(需进库改角色密码)。

5.3 SECRET_KEY——签名密钥

SECRET_KEY 同时承担两个角色(源码 config/session.js → sails.config.session.secret,api/helpers/utils/create-token.js → jwt.sign(..., sails.config.session.secret)):

  • session cookie 签名;
  • 登录令牌(JWT)签名密钥。

生产要求:随机长字符串(≥64 位)。更换即全员下线:旧令牌签名验证失败,所有用户需重新登录(也是「强制全员登出」的正规手段)。实测栈值形如 7f3a9c1d...(64 位十六进制),生成方式任选其一:

openssl rand -hex 32      # 64 位十六进制
head -c 48 /dev/urandom | base64   # 64 位 base64

六、关键参数实测

以下实测均在 2026-10-22 于 3.3.13 官方镜像栈(BASE_URL=http://localhost:8132,初始管理员 admin/q1w2e3r4)完成,可直接复现。

6.1 TOKEN_EXPIRES_IN:默认 365 天逐秒验证

登录获取令牌并解码 JWT 的 iat/exp 字段:

TOKEN=$(curl -s -X POST http://localhost:8132/api/access-tokens -H 'Content-Type: application/json' -d '{"emailOrUsername":"admin","password":"q1w2e3r4"}' | python3 -c 'import sys,json;print(json.load(sys.stdin)["item"])')
echo "${TOKEN:0:50}..."

输出:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjJlZTYzNDA5LTQ3NTEtNDNhZC05YWM2LTg0ZWJhZjdmYTY5NCJ9.eyJpYXQiOjE3OTI2ODc0OTQsInN1YiI6IjE4OTE1OTI0OTM1NDQyNDQyMzAiLCJleHAiOjE4MjQyMjM0OTR9.Nwh9doL0SiMk7z3325hlTB6vi4fwKDjDa5D1KO6rGe0

解码载荷(payload 为 JWT 第二段 base64url):

python3 - "$TOKEN" <<'EOF'
import sys, json, base64, datetime
tok = sys.argv[1]
payload = tok.split('.')[1]
payload += '=' * (-len(payload) % 4)
p = json.loads(base64.urlsafe_b64decode(payload))
iat, exp = p['iat'], p['exp']
print('iat:', datetime.datetime.utcfromtimestamp(iat).isoformat() + 'Z')
print('exp:', datetime.datetime.utcfromtimestamp(exp).isoformat() + 'Z')
print('有效期(秒):', exp - iat, '=', (exp - iat) / 86400, '天')
print('payload 其他字段:', {k: v for k, v in p.items() if k not in ('iat', 'exp')})
EOF

输出:

iat: 2026-10-22T16:45:01Z
exp: 2027-10-22T16:45:01Z
有效期(秒): 31536000 = 365.0 天
payload 其他字段: {'sub': '1891592493544244230'}

结论:默认 TOKEN_EXPIRES_IN=365 生效,exp = iat + 365×86400 与源码公式一致。设为 30 天后同样方法验证 exp-iat = 2592000 秒即认为生效。

6.2 AUTH_RATE_LIMIT:默认 5 次失败即锁定

用脚本连续 6 次错误密码登录(每轮记录状态码与响应体),再试正确密码:

for i in 1 2 3 4 5 6; do printf '第 %d 次: ' $i
  curl -s -o /dev/null -w '%{http_code} ' -X POST http://localhost:8132/api/access-tokens \
    -H 'Content-Type: application/json' -d '{"emailOrUsername":"admin","password":"wrongpass"}'
  curl -s -X POST http://localhost:8132/api/access-tokens \
    -H 'Content-Type: application/json' -d '{"emailOrUsername":"admin","password":"wrongpass"}'
  echo; sleep 1
done
echo '== 窗口内正确密码也受限 =='
curl -s -o /dev/null -w 'HTTP %{http_code}\n' -X POST http://localhost:8132/api/access-tokens \
  -H 'Content-Type: application/json' -d '{"emailOrUsername":"admin","password":"q1w2e3r4"}'

输出:

第 1 次: 401 {"code":"E_UNAUTHORIZED","message":"Invalid username or password"}
第 2 次: 401 {"code":"E_UNAUTHORIZED","message":"Invalid username or password"}
第 3 次: 401 {"code":"E_TOO_MANY_REQUESTS","message":"tooManyFailedAttempts","tooManyFailedAttempts":"Too many failed attempts - Please try again later."}
第 4 次: 429 {"code":"E_TOO_MANY_REQUESTS","message":"tooManyFailedAttempts","tooManyFailedAttempts":"Too many failed attempts - Please try again later."}
第 5 次: 429 {"code":"E_TOO_MANY_REQUESTS","message":"tooManyFailedAttempts","tooManyFailedAttempts":"Too many failed attempts - Please try again later."}
第 6 次: 429 {"code":"E_TOO_MANY_REQUESTS","message":"tooManyFailedAttempts","tooManyFailedAttempts":"Too many failed attempts - Please try again later."}
== 窗口内正确密码也受限 ==
HTTP 429

说明:脚本每轮发两次请求(一次取状态码、一次取响应体),限流按失败尝试累计计数——第 1–5 次失败依次累计,第 5 次失败达上限(响应 401 + E_TOO_MANY_REQUESTS),第 6 次起全部 429。对应服务端日志:

2026-10-22 16:45:08 [WARN] Invalid password! (IP: 10.89.72.1)
2026-10-22 16:45:08 [WARN] Invalid password! (IP: 10.89.72.1)
2026-10-22 16:45:09 [WARN] Invalid password! (IP: 10.89.72.1)
2026-10-22 16:45:09 [WARN] Invalid password! (IP: 10.89.72.1)
2026-10-22 16:45:11 [WARN] Auth rate limit exceeded! (IP: 10.89.72.1)
2026-10-22 16:45:12 [WARN] Auth rate limit exceeded! (IP: 10.89.72.1)
...

60 秒窗口过后重试正确密码:

sleep 60
curl -s -o /dev/null -w 'HTTP %{http_code}\n' -X POST http://localhost:8132/api/access-tokens -H 'Content-Type: application/json' -d '{"emailOrUsername":"admin","password":"q1w2e3r4"}'

输出:

HTTP 200

结论:默认 maxAttempts=5、windowMs=60000 行为与源码一致——窗口内正确密码也被拒(防爆破的预期设计),窗口过后自动解锁,无需重启。

6.3 LOG_LEVEL:应用日志过滤生效,框架日志不受控

默认(未设 LOG_LEVEL,生产模式等效 warn)下应用日志只有 WARN 及以上(见 6.2 节 [WARN] 行),启动期 sails 框架另有 debug: 前缀提示。将 LOG_LEVEL: error 写入应用容器环境并重建后,重复 6.2 节的错误登录:

docker compose logs 4gaBoards --since 1m | grep -c 'WARN'

输出:

0

而框架级 debug: 行(如 onlyAllowOrigins 提示)仍然出现。结论:

  • LOG_LEVEL 过滤的是 4ga Boards 应用自身日志(winston,格式 YYYY-MM-DD HH:mm:ss [LEVEL] 消息,同时写控制台与 logs/4gaBoards.log 文件);
  • sails 框架自身的 debug: 提示不经该变量过滤——排障时可利用这一点保留框架线索;
  • 需要完整请求级日志时设 LOG_LEVEL=info 或 verbose;生产追求安静用默认 warn。

6.4 首建类参数:仅首次初始化生效

DEFAULT_ADMIN_* 生效实测(compose 首启时显式覆盖为 admin/q1w2e3r4)已在 《4ga Boards 3.3.13 Docker Compose 部署指南》 第五章验证:登录接口以该账号密码成功换取令牌。生效机制实查(server/db/init.js + db/seeds/default.js):

// db/init.js(节选)
const isExists = await knex.schema.hasTable(knexfile.migrations.tableName);
await knex.migrate.latest();
if (!isExists) {
  await knex.seed.run();   // 仅当迁移表不存在(全新库)才执行种子
}

即:种子脚本只在数据库从零建立时读取 DEFAULT_* 系列变量。已运行的实例修改这些变量并重启,管理员账号与注册开关不会变化——已存在的账号请走界面管理或直接操作数据库。全新部署(删卷重建/新库)前把这些变量一次配好,是唯一正确的使用姿势。

七、生产配置模板

7.1 Docker Compose 模板(中小团队 50 人以内)

资源规格:应用容器实测常驻内存约 230 MB,PostgreSQL 空库约 60 MB;建议 2 vCPU / 4 GB 内存 / 20 GB 磁盘起步(磁盘按附件量另计,默认单附件 25 MB)。

name: 4ga-boards-prod-stack
services:
  db:
    image: postgres:18-alpine
    restart: unless-stopped
    environment:
      POSTGRES_DB: 4gaBoards
      POSTGRES_PASSWORD: <数据库密码>          # 首次初始化生效,此后修改需进库
    volumes:
      - db-data:/var/lib/postgresql/data
    healthcheck:
      test: ['CMD-SHELL', 'pg_isready -U postgres']
      interval: 10s
      timeout: 5s
      retries: 5
  4gaBoards:
    image: ghcr.io/rargames/4gaboards:3.3.13
    restart: unless-stopped
    depends_on:
      db:
        condition: service_healthy
    ports:
      - '1337:1337'
    environment:
      NODE_ENV: production
      BASE_URL: https://boards.example.com      # 必填:对外地址,改域名即改这里
      SECRET_KEY: <openssl rand -hex 32 生成>   # 必填:更换即全员登出
      DATABASE_URL: postgresql://postgres:<数据库密码>@db:5432/4gaBoards
      TZ: Asia/Shanghai
      # —— 可选加固 ——
      DEFAULT_ADMIN_USERNAME: admin             # 首建类:仅首次生效
      DEFAULT_ADMIN_PASSWORD: <强口令>
      DEFAULT_REGISTRATION_ENABLED: 'false'     # 关闭开放注册
      SYSTEM_NOTIFICATIONS_DISABLED: 'true'     # 内网/离线部署关闭官方通知
      LOG_LEVEL: warn
volumes:
  db-data:

Redis 仅在「上传限流计数跨实例共享 / 多副本部署」时需要,单实例用默认 memory 存储即可,无需部署。

7.2 源码手动安装模板(server/.env)

NODE_ENV=production
BASE_URL=https://boards.example.com
SECRET_KEY=<openssl rand -hex 32 生成>
DATABASE_URL=postgresql://boards:<数据库密码>@localhost:5432/4gaBoards
TZ=Asia/Shanghai
LOG_LEVEL=warn

完整源码安装流程(Node 24 构建、systemd 托管)见 《Ubuntu 22.04 安装 4ga Boards 3.3.13 指南》。

7.3 常见场景速查

场景关键参数备注
换域名/端口BASE_URL同步改反向代理与 IdP 回调登记
强制全员重新登录换 SECRET_KEY旧令牌全部失效
关闭自注册、管理员建号DEFAULT_REGISTRATION_ENABLED: 'false'首建类,新库前设置
防爆破加固AUTH_RATE_LIMIT_MAX_ATTEMPTS(默认 5)窗口时长有 60 秒下限
大附件需求ATTACHMENT_MAX_BYTES注意反向代理 client_max_body_size 同步调大
多实例负载均衡UPLOAD_RATE_LIMIT_STORE=redis + UPLOAD_RATE_LIMIT_REDIS_URL登录限流计数为实例内存态,多副本时每实例独立计数
内网离线部署SYSTEM_NOTIFICATIONS_DISABLED: 'true'避免反复请求官方通知服务
接入 OIDCOIDC_* 六件套或 OIDC_ISSUER_URL 一件套回调 <BASE_URL>/auth/oidc

八、常见问题

Q1:修改 DEFAULT_ADMIN_PASSWORD 后重启,管理员密码没变? 首建类参数只在数据库首次初始化的种子阶段读取(见 6.4 节实测)。已有库改密码:管理员登录界面改,或管理员 API 改;忘记密码且无其他管理员时,用 PostgreSQL 直连更新 users 表对应字段(操作前先备份,备份命令见 《4ga Boards 3.3.13 常用 CLI 命令与工具详解》)。

Q2:AUTH_RATE_LIMIT_WINDOW_MS 设了 30000(30 秒)不生效? 源码对窗口时长强制下限 60 秒(Math.max(parseInt(..., 10) || 60 * 1000, 60 * 1000)),小于 60000 的值一律按 60000 处理。要更长的锁定时间可以设大(如 300000 = 5 分钟),要更短则无效。

Q3:页面能打开,但卡片/列表不实时刷新? BASE_URL 与浏览器实际访问地址的 origin 不一致所致(WebSocket 握手被 onlyAllowOrigins 拒绝)。保证用户浏览器地址栏 origin 与 BASE_URL 完全一致(协议、域名、端口都算),或经反向代理透传后保持同源。

Q4:LOG_LEVEL=error 了为什么日志里还有 debug: 开头的行? 那些行来自 Sails 框架内置日志,不走应用级 LOG_LEVEL 过滤(见 6.3 节实测)。应用自身日志已按 error 过滤(WARN 计数为 0)。

Q5:SECRET_KEY 可以留空用默认吗? 不可以。v3.3.13 没有默认值,缺失时 session secret 为 undefined,登录令牌签发直接失败。必填三件套(BASE_URL/DATABASE_URL/SECRET_KEY)缺一不可。

Q6:附件上限调大后上传仍报错? 除 ATTACHMENT_MAX_BYTES 外,链路上的反向代理(Nginx client_max_body_size)与 BOARD_IMPORT_MAX_*(仅影响导入功能)是独立限制,需逐段核对。另注意上传接口受 UPLOAD_RATE_LIMIT_* 限流(默认 60 秒 30 次),批量上传时超限会得到 429。

九、参考链接

  1. 官方 Docker 变量文档:https://docs.4gaboards.com/docs/dev/install/docker-vars/
  2. 官方手动安装变量文档:https://docs.4gaboards.com/docs/dev/install/manual-vars/
  3. 源码配置目录(本文默认值实查来源):https://github.com/RARgames/4gaBoards/tree/v3.3.13/server/config
  4. CVE-2026-41419(<3.3.5 路径穿越,看板导入,BOARD_IMPORT_* 上限即相关加固面):https://github.com/RARgames/4gaBoards/security/advisories
  5. 本专栏相关篇目:《4ga Boards 3.3.13 介绍与选型指南》、《Ubuntu 22.04 安装 4ga Boards 3.3.13 指南》、《4ga Boards 3.3.13 Docker Compose 部署指南》、《4ga Boards 3.3.13 常用 CLI 命令与工具详解》