Cronmaster 2.4.1 配置参数详解
配置篇:按核心、认证安全、OIDC、界面系统状态、日志、路径执行、调试七组拆解 Cronmaster 2.4.1 全部环境变量及默认值,并对 LOCALE、DISABLE_SYSTEM_STATS、DISABLE_DISK_STATS、AUTH_MAX_LOGIN_ATTEMPTS、SESSION_MAX_AGE_DAYS、FRAME_ANCESTORS、LIVE_UPDATES、MAX_LOGS_PER_JOB 共 8 项给出真实接口回显与响应头实测。
Cronmaster 2.4.1 配置参数详解
目标:把 Cronmaster 2.4.1 的全部环境变量列清楚——每一项做什么、默认值是什么、什么时候必须改——并对其中 8 项做逐项实测,给出真实的接口回显与响应头作为证据。所有默认值取自官方
howto/ENV_VARIABLES.md,所有实测结论取自测试机执行记录(2026-10-27)。配置注入方式不限:systemd 单元的
Environment=、进程管理器的环境变量块、或任何能向进程传入环境变量的方式都等价。本篇以「设置环境变量 → 重启进程 → 观察接口」的方式逐项验证。
一、测试环境与验证方法
| 项目 | 实测值 |
|---|---|
| 操作系统 | Ubuntu 22.04.5 LTS |
| 应用版本 | Cronmaster 2.4.1 |
| 登录用户 | root,示例密码 q1w2e3r4 |
| 应用监听 | 3000(对外由反向代理暴露) |
| 验证手段 | /api/system-stats、/api/auth/login、/api/events、响应头、日志目录 |
验证方法统一为三步:修改环境变量 → 重启应用进程 → 用对应接口或响应头核对行为变化。这样得到的结论可复现,且不依赖界面文案。
二、全部环境变量总表
2.1 核心
| 变量 | 默认值 | 作用 |
|---|---|---|
NODE_ENV | 无 | 生产环境必须设为 production,否则会以开发模式运行 |
APP_URL | 自动探测 | 实例的公网 URL,如 https://cron.example.com。启用 OIDC 时必填 |
LOCALE | en | 界面语言。内置 en、zh(简体中文)等;支持 data/translations/<locale>.json 自定义 |
HOME | /home | 主目录覆盖,一般无需改动 |
2.2 认证与安全
| 变量 | 默认值 | 作用 |
|---|---|---|
AUTH_PASSWORD | 无 | 密码登录口令。不设置且未启用 SSO 时,界面无认证保护 |
AUTH_MAX_LOGIN_ATTEMPTS | 未启用 | 暴力破解防护。同一客户端连续失败达到该次数后返回 429,直到锁定窗口结束。未设置即完全不限速 |
AUTH_LOCKOUT_MINUTES | 15 | 上项的统计窗口与锁定时长(分钟) |
SESSION_MAX_AGE_DAYS | 30 | 登录会话有效期(天),支持小数,0.5 即 12 小时 |
FRAME_ANCESTORS | 未启用 | 防点击劫持。允许嵌入 UI 的源列表,写入 Content-Security-Policy: frame-ancestors。self 仅允许自身,none 禁止嵌入,也可写具体域名 |
API_KEY | 无 | 保护 /api/* 接口的 Bearer Token。不保护 Web 界面;未设置时 API 完全公开 |
HTTPS | false | 强制 HTTPS-only Cookie 与跳转 |
2.3 OIDC / SSO
| 变量 | 默认值 | 作用 |
|---|---|---|
SSO_MODE | 无 | 设为 oidc 启用 OIDC 单点登录 |
OIDC_ISSUER | 无 | 身份提供方 issuer URL |
OIDC_CLIENT_ID | 无 | 客户端 ID |
OIDC_CLIENT_SECRET | 无 | 客户端密钥(机密客户端需要) |
OIDC_LOGOUT_URL | 无 | 自定义登出地址 |
OIDC_GROUPS_SCOPE | groups | 请求用户组所用的 scope。Entra ID 等不支持该 scope 的提供方应设为空、no 或 false |
OIDC_USER_GROUPS | 无 | 允许登录的组白名单,逗号分隔 |
OIDC_USER_ROLES | 无 | 允许登录的角色白名单,逗号分隔 |
OIDC_AUTO_REDIRECT | false | 仅启用 SSO(无密码)时自动跳转到身份提供方 |
INTERNAL_API_URL | http://localhost:3000 | 特定反代场景下的内部 API 地址覆盖 |
2.4 界面与系统状态
| 变量 | 默认值 | 作用 |
|---|---|---|
NEXT_PUBLIC_CLOCK_UPDATE_INTERVAL | 30000 | 界面时钟刷新间隔(毫秒) |
LIVE_UPDATES | true | 是否启用 SSE 实时推送(任务状态、日志流) |
DISABLE_SYSTEM_STATS | false | 设为 true 彻底关闭系统状态采集(停止轮询并隐藏侧栏) |
DISABLE_DISK_STATS | false | 设为 true 隐藏磁盘空间与 inode 卡片,其余系统状态保留 |
DISK_MOUNTS | / | 要展示的挂载点列表,逗号分隔,最多 8 个。结果缓存 60 秒。只应添加你愿意被探测的挂载点,网络/池化文件系统可能被唤醒 |
2.5 日志
| 变量 | 默认值 | 作用 |
|---|---|---|
MAX_LOG_AGE_DAYS | 30 | 执行日志保留天数 |
MAX_LOGS_PER_JOB | 50 | 每个任务最多保留的日志文件数 |
NEXT_PUBLIC_MAX_LOG_AGE_DAYS | 30 | 浏览器端错误历史保留天数(仅前端) |
2.6 路径与执行
| 变量 | 默认值 | 作用 |
|---|---|---|
HOST_CRONTAB_USER | root | 要读取的 crontab 所属用户,逗号分隔可管理多个用户(如 root,deploy) |
HOST_DATA_DIR | 无 | 数据目录在宿主机上的绝对路径。当应用运行路径与宿主机不一致时需要显式指定,否则写进 crontab 的包装脚本路径会错 |
HOST_SCRIPTS_DIR | 无 | 脚本目录在宿主机上的绝对路径,同上 |
HOST_PROJECT_DIR | 无 | 旧版兼容项,作为最后兜底,映射为 <值>/data 与 <值>/scripts |
EXECUTION_SHELL | 未设置 | 「立即执行」切换用户时使用的 shell。未设置时使用目标用户的登录 shell;nologin/false 用户自动回退 /bin/sh |
STRICT_EXECUTION_USER | false | 设为 true 时,手动执行遇到宿主机上不存在的用户会直接报错,而不是以 root 运行 |
路径解析顺序固定为:HOST_DATA_DIR / HOST_SCRIPTS_DIR → 自动探测 → HOST_PROJECT_DIR。显式设置前两项最稳。
2.7 调试
| 变量 | 默认值 | 作用 |
|---|---|---|
LOG_LEVEL | info | 系统日志级别:error/warn/info/debug |
NEXT_PUBLIC_LOG_LEVEL | info | 浏览器控制台级别(构建期),同时作为 LOG_LEVEL 未设置时的服务端兜底 |
LOG_FORMAT | text | 设为 json 输出单行结构化日志 |
DEBUGGER | false | 等同于 LOG_LEVEL=debug,并输出更详细的错误信息 |
三、8 项逐项实测
以下每一项都给出了修改值、观测手段与真实回显。
3.1 LOCALE:zh-cn 不可用,必须写 zh
设置:LOCALE=zh-cn
现象:启动日志出现
Cannot find module '../../../_translations/zh-cn.json'
界面保持英文。
原因:2.4.1 内置文件名为 zh.json,不存在 zh-cn.json。找不到指定 locale 时应用静默回退 en.json,只在日志留一行。
改为 LOCALE=zh 后界面正常显示中文。结论:LOCALE=zh-cn 是无效值,这是 2.4.1 的真实缺陷,网上常见的 zh-cn 写法在这版不能用。
3.2 DISABLE_SYSTEM_STATS=true:接口返回 null
设置:DISABLE_SYSTEM_STATS=true
观测:
curl -s -o body -w 'HTTP %{http_code}\n' \
-H 'Authorization: Bearer <API_KEY>' http://127.0.0.1:3000/api/system-stats
回显:
HTTP 200
响应体:
null
结论:开启后接口仍返回 200,但 body 为 JSON null;侧栏的 CPU/内存/网络卡片随之隐藏。前端必须能处理 null——若自建脚本无脑 JSON.parse 后取字段会报错。
3.3 DISABLE_DISK_STATS=true:disks 键整体消失
设置:DISABLE_DISK_STATS=true
观测:对比接口返回的顶层键。
curl -s -H 'Authorization: Bearer <API_KEY>' http://127.0.0.1:3000/api/system-stats
基线(未开启)时顶层键:
['uptime', 'uptimeSeconds', 'memory', 'cpu', 'network', 'systemStatus', 'gpu', 'disks']
开启后:
['uptime', 'uptimeSeconds', 'memory', 'cpu', 'network', 'systemStatus', 'gpu']
结论:disks 键被整体移除,而不是置空;uptime/memory/cpu 等不受影响。写接口对接代码时要按「键可能不存在」处理,不能假设 disks 恒在。
3.4 AUTH_MAX_LOGIN_ATTEMPTS + AUTH_LOCKOUT_MINUTES:超限返回 429
设置:AUTH_MAX_LOGIN_ATTEMPTS=3、AUTH_LOCKOUT_MINUTES=1
观测:连续 4 次错误密码登录。
for i in 1 2 3 4; do
curl -s -o body -w "attempt $i: HTTP %{http_code} " \
-X POST -H 'Content-Type: application/json' \
-d '{"password":"wrongpass"}' http://127.0.0.1:3000/api/auth/login
cat body; echo
done
回显:
attempt 1: HTTP 401 {"success":false,"message":"Invalid password"}
attempt 2: HTTP 401 {"success":false,"message":"Invalid password"}
attempt 3: HTTP 401 {"success":false,"message":"Invalid password"}
attempt 4: HTTP 429 {"success":false,"message":"Too many failed attempts, try again later"}
结论:第 4 次(超过阈值 3)被锁定,返回 HTTP 429 而非 401,message 明确告知稍后再试。锁定窗口 1 分钟后自动解除。
重要前提:客户端身份按 X-Forwarded-For 第一段、其次 X-Real-IP 识别。若前面没有反向代理设置这些头,所有请求会被算作同一来源,等于把全站锁死。因此这项功能只在「有反代且正确透传 IP」的架构下开启。
3.5 SESSION_MAX_AGE_DAYS=0.5:Cookie 有效期 12 小时
设置:SESSION_MAX_AGE_DAYS=0.5
观测:正确登录后看响应头。
curl -s -D - -o /dev/null -X POST -H 'Content-Type: application/json' \
-d '{"password":"q1w2e3r4"}' http://127.0.0.1:3000/api/auth/login
回显(节选):
set-cookie: cronmaster-session=<...>; Path=/; Expires=...; Max-Age=43200; HttpOnly; SameSite=lax
Max-Age=43200 即 12 小时,与 0.5 × 86400 完全一致。
结论:支持小数天,换算精确;默认 30 对应 Max-Age=2592000。该值同时影响密码登录与 SSO 会话。
3.6 FRAME_ANCESTORS:写入 CSP 响应头
设置:FRAME_ANCESTORS=https://ops.example.com
观测:
curl -s -D - -o /dev/null http://127.0.0.1:3000/login
回显(节选):
HTTP/1.1 200 OK
content-security-policy: frame-ancestors https://ops.example.com
结论:变量值被原样拼进 Content-Security-Policy 的 frame-ancestors 指令。未设置时该响应头不存在(即默认允许被嵌入)。生产环境建议至少设 self。
3.7 LIVE_UPDATES=false:事件流接口返回 503
设置:LIVE_UPDATES=false
观测:
curl -s --max-time 4 -o body -w 'HTTP %{http_code} type=%{content_type}\n' \
-H 'Authorization: Bearer <API_KEY>' -H 'Accept: text/event-stream' \
http://127.0.0.1:3000/api/events
回显:
HTTP 503 type=application/json
{"error":"Live updates are disabled"}
结论:关闭 SSE 后,/api/events 返回 503 与 JSON 错误体,而不是空流挂起。界面不再自动刷新任务状态,需要手动刷新页面;执行日志的实时回放同时失效,但日志文件仍完整写入。
3.8 MAX_LOGS_PER_JOB=1:日志自动裁剪到 1 份
设置:MAX_LOGS_PER_JOB=1
前置状态:某任务已有 3 份日志文件(2 份历史 + 1 份新执行)。
观测:手动执行一次任务,然后读取任务列表(读取会触发清理)。
ls data/logs/74r1-rp4h/ # 执行前
curl -s -H 'Authorization: Bearer <API_KEY>' \
'http://127.0.0.1:3000/api/cronjobs/74r1-rp4h/execute?runInBackground=false'
curl -s -H 'Authorization: Bearer <API_KEY>' http://127.0.0.1:3000/api/cronjobs > /dev/null
ls data/logs/74r1-rp4h/ # 清理后
回显(执行前):
2026-10-27_20-19-12.log
2026-10-27_20-19-44.log
2026-10-27_20-24-50.log
回显(清理后):
2026-10-27_20-24-50.log
结论:按数量上限裁剪,保留最新一份。清理触发点有两个:从界面/API 发起的任务执行结束后,以及读取任务日志时(每任务最多 5 分钟一次)。MAX_LOG_AGE_DAYS 先按时间删,再按数量删。
四、实测之外的两项说明
4.1 API_KEY 的实际行为
设置 API_KEY 后,未带 Authorization: Bearer ... 的 /api/cronjobs 请求返回:
HTTP 401
{"error":"Unauthorized","message":"Authentication required. Use session cookie or API key (Bearer token)."}
而 /api/health 始终免认证(供健康检查使用),这是有意的设计,不要拿它当安全探针。
4.2 LOG_LEVEL / LOG_FORMAT 的生效条件
这两项是进程环境变量,必须真正传入进程环境。若通过外层编排工具间接设置,需确认变量确实出现在进程环境里(/proc/<pid>/environ 可查)。启动日志里的自检块会回显 logLevel 与 logFormat 的最终值,可作为快速核对手段:
logLevel: 'info',
logFormat: 'text',
自检块中同时包含 locale、bearerAuth、liveUpdates、systemStats、maxLogsPerJob、maxLogAgeDays 等,排查配置是否生效时先看这一段,比逐个接口试快得多。
五、配置建议清单
| 场景 | 建议配置 |
|---|---|
| 最小可用 | NODE_ENV=production、AUTH_PASSWORD、HOST_CRONTAB_USER=root |
| 中文界面 | LOCALE=zh(不要 zh-cn) |
| 对外暴露 | AUTH_PASSWORD + API_KEY + FRAME_ANCESTORS=self + HTTPS=true + 反代透传 X-Forwarded-For |
| 开启限速 | AUTH_MAX_LOGIN_ATTEMPTS=5 + AUTH_LOCKOUT_MINUTES=15,且确认反代设置 IP 头 |
| 会话收紧 | SESSION_MAX_AGE_DAYS=1(或 0.5) |
| 日志控量 | MAX_LOG_AGE_DAYS=7 + MAX_LOGS_PER_JOB=20 |
| 低配/省心 | DISABLE_SYSTEM_STATS=true;只保留磁盘卡片时用 DISABLE_DISK_STATS=false + DISK_MOUNTS=/ |
| 多用户 crontab | HOST_CRONTAB_USER=root,deploy,backup |
| 路径严格 | HOST_DATA_DIR / HOST_SCRIPTS_DIR 显式写宿主机绝对路径 |
六、结论
Cronmaster 2.4.1 的配置面很收敛:核心只需要 NODE_ENV、AUTH_PASSWORD、HOST_CRONTAB_USER 三项,其余都是按场景叠加。实测确认了 8 项行为,其中两个必须记住的陷阱:
LOCALE=zh-cn无效,只能用zh;AUTH_MAX_LOGIN_ATTEMPTS依赖反代透传真实 IP,裸奔开启会把全站锁死。
另外,DISABLE_SYSTEM_STATS 返回 null、DISABLE_DISK_STATS 直接删除 disks 键这两个行为,对接接口时需按「值可能为空/键可能缺失」处理。
延伸阅读:本专栏《Cronmaster 2.4.1 API 详解》逐端点给出请求与响应;本专栏的部署篇给出这些变量在编排文件中的写法。