Habitica v5.52.0 常用 CLI 命令与工具详解
Habitica v5.52.0 自托管运维命令手册:systemd 服务管理、npm/gulp 构建测试脚本族、REST API 注册/登录/四类任务/cron 实操、MongoDB 备份恢复闭环与数据形态巡检、BullMQ 邮件队列运维,全部命令 Ubuntu 22.04 实测附回显。
Habitica v5.52.0 常用 CLI 命令与工具详解
目标:整理 Habitica v5.52.0 自托管日常运维的命令与工具箱——systemd 服务管理、npm 脚本族与 gulp 构建任务、REST API 用户/任务/每日结算的命令行操作、MongoDB 备份恢复闭环与数据形态巡检、Redis 队列运维,全部命令在 Ubuntu 22.04 服务器的 v5.52.0 环境实测并附回显。安装与配置参数背景分别见本专栏安装指南篇与配置详解篇。
一、环境信息
本篇实测环境:
- 操作系统:Ubuntu 22.04.5 LTS(x86_64);Habitica v5.52.0(commit 12091ca)
- 服务形态:systemd 单元
habitica-web,入口/opt/habitica/website/transpiled-babel/index.js(NODE_ENV=production,WEB_CONCURRENCY=1) - 依赖组件:Node.js v20.20.2 / MongoDB v7.0.45(单节点副本集 rs)/ Redis v8.10.3
- 服务地址:
http://10.89.71.10:3000(本机内网 IP,读者替换) - 演示账号:
habadmin/q1w2e3r4(注册流程见 4.2 节,apiToken见 4.3 节) - 工作目录:
/opt/habitica(下文命令默认在此执行)
💡 说明:Habitica 没有自带的管理 CLI(不同于 NodeBB 的
./nodebb命令族),日常运维由三部分组成:systemd 管进程、npm/gulp 管构建与测试、REST API + 数据库工具管业务数据。本篇按这三条线展开。
二、服务进程管理(systemd)
2.1 启停与状态
sudo systemctl start habitica-web
systemctl is-active habitica-web mongod redis-server
active
active
active
systemctl status habitica-web --no-pager | head -12
● habitica-web.service - Habitica Web Server
Loaded: loaded (/etc/systemd/system/habitica-web.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2026-10-28 07:40:05 UTC; 15s ago
Main PID: 8645 (node)
Tasks: 18 (limit: 19553)
Memory: 160.4M
CPU: 1.894s
CGroup: /system.slice/habitica-web.service
├─8645 /usr/bin/node /opt/habitica/website/transpiled-babel/index.js
└─8652 /usr/bin/node /opt/habitica/website/transpiled-babel/index.js
状态解读:WEB_CONCURRENCY=1 时进程树为 1 主 + 1 worker——主进程(Main PID 8645)只负责 cluster 监控与 worker 重拉,HTTP 流量在 worker(8652)上;内存统计 160.4MB 是两进程合计。停用、重启与开机自启:
sudo systemctl stop habitica-web && systemctl is-active habitica-web
inactive
sudo systemctl restart habitica-web && systemctl is-active habitica-web
active
systemctl is-enabled habitica-web
enabled
改配置后的标准生效动作(新开 shell 逐条执行):
sudo systemctl daemon-reload && sudo systemctl restart habitica-web
2.2 日志查看(journalctl)
journalctl -u habitica-web --no-pager -n 20
实测默认情况下只有 systemd 的启停生命周期行(Started/Stopped habitica-web.service),看不到应用日志——生产模式 winston 默认无 Console transport(配置详解篇 6.3 节)。排障时给单元临时加环境变量开启:
sudo systemctl edit habitica-web
写入:
[Service]
Environment=ENABLE_CONSOLE_LOGS_IN_PROD=true
sudo systemctl daemon-reload && sudo systemctl restart habitica-web
之后 journalctl -u habitica-web -f 可实时看到文本+JSON 双格式应用日志。排障结束建议移除该覆盖(sudo systemctl revert habitica-web)恢复静默。
2.3 手动前台启动(对照与应急)
systemd 之外,应急排查可直接前台运行(能看到 winston 的 no-transports 提示与 worker 崩溃堆栈):
sudo -u habitica env NODE_ENV=production node website/transpiled-babel/index.js
开发态另有两个 npm 启动脚本(源码 package.json scripts 实查):npm start(node --watch ./website/server/index.js,带文件监听自动重启,运行源码目录并实时挂 @babel/register 转译)与 npm run debug(附加 --inspect 暴露调试端口)。注意开发态入口跑的是 website/server/ 源码,生产 systemd 单元跑的是 website/transpiled-babel/ 预转译产物,两套入口共用同一份 config.json。
2.4 worker 崩溃循环的识别
worker 异常退出时主进程自动重拉,日志特征是 worker:xxxx disconnect! new worker:yyyy fork 循环出现。配置详解篇实测的三个崩溃根因(PAYPAL_MODE/FLAG_REPORT_EMAIL/GOOGLE_CLIENT_ID/SECRET 缺失)均以此形态表现。快速判别:
ps -ef | grep 'transpiled-babel' | grep -v grep | wc -l
4
数值应稳定为 WEB_CONCURRENCY + 1;若 PID 短时间内持续变化,即崩溃循环,优先查配置。
三、构建与测试命令(npm 脚本族)
3.1 常用脚本一览
源码 package.json 的 scripts 字段(v5.52.0 实查)中与运维相关的子集:
| 命令 | 实际执行 | 用途 |
|---|---|---|
npm start | node --watch ./website/server/index.js | 开发态启动(源码+实时转译+watch) |
npm run debug | node --watch --inspect ./website/server/index.js | 开发态启动+调试端口 |
npm run client:build | cd website/client && npm run build | 前端生产构建(vite build) |
npm run client:dev | cd website/client && npm run serve | 前端开发服务(vite dev) |
npm run lint | eslint 全仓 + 客户端 lint(带 --fix) | 代码风格修复 |
npm run lint-no-fix | eslint 全仓 + 客户端 lint(只查不改) | 代码风格检查 |
npm run client:unit | cd website/client && npm run test:unit | 前端单元测试(vitest) |
npm run test:api-v3 等 | gulp test:api-v3 族 | API 集成测试(gulp 驱动) |
npx gulp build:prod | Babel 预转译 + 内容缓存 | 生产构建(后端) |
npx gulp sprites:compile | 雪碧图编译 | 素材变更后重建 |
3.2 前端构建(client:build 实测)
cd /opt/habitica && sudo -u habitica npm run client:build
输出节选(实测):
vite v6.4.1 building for production...
transforming...
rendering chunks...
✓ built in 8.74s
产物落在 website/client/dist/(实测 93MB),生产模式由服务端直接托管该目录。改前端源码或升级版本后重跑即可。
3.3 后端预转译(gulp build:prod 实测)
cd /opt/habitica && sudo -u habitica env NODE_ENV=production npx gulp build:prod
输出节选(实测):
[07:31:42] Finished 'build:babel' after 6.7 s
[07:31:42] Finished 'build:cache' after 5.08 s
[07:31:42] Finished 'build:prod' after 7.16 s
产出 website/transpiled-babel/(服务端)与 website/common/transpiled-babel/(公共逻辑)。必须带 NODE_ENV=production——gulpfile 按该变量选择 prod/dev 分支,漏带则不产出转译目录。升级 Habitica 版本后必须重跑本命令再重启服务。
3.4 代码检查(lint-no-fix 实测)
cd /opt/habitica && sudo -u habitica npm run lint-no-fix
输出节选(实测,耗时约 1-2 分钟):
✖ 542 problems (0 errors, 542 warnings)
0 errors and 37 warnings potentially fixable with the `--fix` option.
v5.52.0 源码基线本身携带 542 条 warning、0 error——这是上游代码的固有状态(命令退出码非 0 也源于此),修改自定义代码后对比 warning 增量即可判断自己是否引入问题。需要自动修复用 npm run lint(带 --fix)。
3.5 前端单元测试(client:unit 实测)
cd /opt/habitica && sudo -u habitica npm run client:unit
结果摘要(实测):
Test Files 5 failed | 27 passed | 2 skipped (34)
Tests 174 passed | 5 skipped (179)
174 个用例全部通过;5 个测试文件失败属上游基线状态(文件级 setup 依赖导致,用例本身无失败),升级后同样以「用例通过数」为对照基线。API 集成测试族(npm run test:api-v3 等)依赖完整数据库环境且会动测试库,本篇未全量执行,仅实测了上述前端单测,特此说明。
四、用户与认证:命令行操作 API
Habitica 的业务操作走 REST API(/api/v3 与 /api/v4,v4 为 v3 的路由代理与部分端点覆盖)。命令行交互用 curl + 两个认证头:x-api-user(用户 ID)与 x-api-key(API Token)。
4.1 注册用户(排障实录:保留词拦截)
curl -s -X POST http://10.89.71.10:3000/api/v4/user/auth/local/register \
-H 'Content-Type: application/json' \
-d '{"username":"habadmin","password":"q1w2e3r4","email":"admin@example.com","confirmPassword":"q1w2e3r4"}' | head -c 200
{"success":true,"data":{"auth":{"local":{"email":"admin@example.com","username":"habadmin","lowerCaseUsername":"habadmin","has_password":true}, ...
⚠️ 排障实录:用户名
admin实测被拒——{"success":false,"error":"BadRequest","message":"Usernames may not contain restricted words."}。服务端保留词库website/server/libs/bannedWords.js收录了 admin 等词,校验为整词边界正则(libs/user/validation.js:11),故habadmin这类复合词可通过。密码强度仅要求长度,q1w2e3r4(8 位)实测可注册,生产请用强口令。
4.2 登录获取 apiToken
curl -s -X POST http://10.89.71.10:3000/api/v4/user/auth/local/login \
-H 'Content-Type: application/json' \
-d '{"username":"habadmin","password":"q1w2e3r4"}'
{"success":true,"data":{"id":"118ccfe6-2c4d-46be-9f9e-3b2d345d55d5","apiToken":"<32位UUID>","newUser":false,"username":"habadmin"},"appVersion":"5.52.0"}
v4 登录响应极简:id 即认证用户 ID(x-api-user),apiToken 即认证密钥(x-api-key)。两者也可在 Web 端「设置 → API」页查看。Web 端管理员/普通用户权限差异由站内_roles_控制,命令行 API 默认以账号自身权限执行。
4.3 带认证头查询用户(实测)
U=118ccfe6-2c4d-46be-9f9e-3b2d345d55d5
T=<你的apiToken>
curl -s http://10.89.71.10:3000/api/v4/user -H "x-api-user: $U" -H "x-api-key: $T" | \
python3 -c "import json,sys; u=json.load(sys.stdin)['data']; s=u['stats']; print('name:',u['profile']['name'],'| lvl:',s['lvl'],'| hp:',s['hp'],'| xp:',s['exp'],'| gold:',s['gp'])"
name: habadmin | lvl: 1 | hp: 50 | xp: 0 | gold: 0
认证头错误时的实测表现(用于判断排障方向):
curl -s http://10.89.71.10:3000/api/v4/user -H "x-api-user: $U" -H "x-api-key: wrong-token" | head -c 120
{"success":false,"error":"NotAuthorized","message":"Not authorized to access data."}
4.4 限流注意
开启限流后(配置详解篇 7.3 节实测:v4 桶 200 点、未认证请求按 IP 每次扣 5 点),命令行批量脚本要注意扣点节奏,桶耗尽会收到 429 与 Retry-After 头;注册与登录接口单次扣 10 点。
五、任务管理:四类任务的命令行操作
Habitica 的核心数据模型是四类任务:habit(习惯,可加减分)、daily(每日,cron 结算)、todo(待办,完成即删入历史)、reward(奖励,消耗金币兑换)。
5.1 创建四类任务(实测)
curl -s -X POST http://10.89.71.10:3000/api/v4/tasks/user \
-H "x-api-user: $U" -H "x-api-key: $T" -H 'Content-Type: application/json' \
-d '{"text":"喝水打卡","type":"habit"}' | head -c 150
{"success":true,"data":{"_id":"fb97e550-b89d-4daa-b836-46a65e015b5c","text":"喝水打卡","type":"habit",...
其余三类同接口换 type:daily(可带 everyX/frequency 周期字段)、todo、reward(带 value 金币价)。实测创建记录:
habit | fb97e550-b89d-4daa-b836-46a65e015b5c | 喝水打卡
daily | 6433db21-f813-47e9-ac67-5e9c0e2cca53 | 早睡
todo | b04e34e1-638e-4442-ba88-4d767894baed | 读完一章书
reward | 6a39de4f-38b9-444f-80dd-137f1f1141c0 | 看剧30分钟 (value: 10)
列表查询(注意 v4 返回扁平数组):
curl -s http://10.89.71.10:3000/api/v4/tasks/user -H "x-api-user: $U" -H "x-api-key: $T" | \
python3 -c "
import json,sys
for t in json.load(sys.stdin)['data']:
print(t['type'],'|',t['text'],'| value:',round(t.get('value',0),2),'| completed:',t.get('completed'))
"
habit | 喝水打卡 | value: 0.0 | completed: None
daily | 早睡 | value: 0 | completed: False | streak: 0
todo | Join Habitica (Check me off!) | value: 0 | completed: False
reward | 看剧30分钟 | value: 10
💡 说明:已完成的 todo 不出现在默认列表(实测:完成「读完一章书」后该任务从返回中消失),需要查历史时用完成态过滤参数或直接查库(第六节)。
5.2 Habit 加减分(实测数值反馈)
curl -s -X POST http://10.89.71.10:3000/api/v4/tasks/fb97e550-b89d-4daa-b836-46a65e015b5c/score/up \
-H "x-api-user: $U" -H "x-api-key: $T"
响应 data 为更新后的 exp(实测 6:1 级角色 habit 加分得 6 经验)。随即查用户数值验证:
lvl 1 hp 50 xp 6 gp 1 mp 11
减分(坏习惯):
curl -s -X POST http://10.89.71.10:3000/api/v4/tasks/fb97e550-b89d-4daa-b836-46a65e015b5c/score/down \
-H "x-api-user: $U" -H "x-api-key: $T"
实测 hp 50 → 49(坏习惯扣血)。
5.3 Todo 完成与 Reward 兑换(实测)
完成 todo(score/up 即勾选完成):
curl -s -X POST http://10.89.71.10:3000/api/v4/tasks/b04e34e1-638e-4442-ba88-4d767894baed/score/up \
-H "x-api-user: $U" -H "x-api-key: $T"
实测数值变化:xp 6 → 12、gp 1 → 2(todo 给经验+金币且额度高于 habit)。兑换 reward 用 score/down(消费金币):
curl -s -X POST http://10.89.71.10:3000/api/v4/tasks/6a39de4f-38b9-444f-80dd-137f1f1141c0/score/down \
-H "x-api-user: $U" -H "x-api-key: $T"
{"success":false,"error":"NotAuthorized","message":"Not Enough Gold"}
⚠️ 排障实录:金币不足时实测返回 401
Not Enough Gold(当时仅 2 金币,奖励标价 10)。这是业务校验而非故障——先完成足量 habit/todo 攒金币,或把 reward 的value调低(PUT /api/v4/tasks/:id改值)后再兑换。
5.4 每日结算 cron(实测)
curl -s -X POST http://10.89.71.10:3000/api/v4/cron -H "x-api-user: $U" -H "x-api-key: $T" | head -c 150
{"success":true,"data":{},"notifications":[{"type":"ACHIEVEMENT","data":{"achievement":"completedTask","icon":"achievement-completedTask","message":"...
cron 结算成功并随响应下发成就通知(首次完成任务获得 completedTask 成就)。cron 的跨天结算规则(未完成 daily 扣血、Boss 伤害等)由 CRON_SAFE_MODE/CRON_SEMI_SAFE_MODE 控制,语义与源码位置见配置详解篇第九节。
六、MongoDB 运维:数据形态与备份恢复
6.1 数据形态巡检(mongosh)
用户文档核心字段(认证与数值统计):
mongosh --quiet --eval 'const u=db.getSiblingDB("habitica").users.findOne({"auth.local.username":"habadmin"},{_id:0,"auth.local.username":1,"auth.local.email":1,"stats.lvl":1,"stats.hp":1,"stats.gp":1}); printjson(u)'
{
auth: {
local: { email: 'admin@example.com', username: 'habadmin' }
},
stats: { hp: 49, gp: 2, lvl: 1 }
}
任务文档(tasks 集合,四类同集合以 type 区分):
mongosh --quiet --eval 'const t=db.getSiblingDB("habitica").tasks.findOne({type:"habit"},{_id:0,text:1,type:1,value:1,userId:1}); printjson(t)'
{
type: 'habit',
text: '喝水打卡',
value: 4.255940168063077e-7,
userId: '118ccfe6-2c4d-46be-9f9e-3b2d345d55d5'
}
value 是 habit 的动态难度值(连减趋近 0、连加回升),也是金币/经验结算的输入。任务通过 userId 关联用户。
6.2 备份恢复闭环(mongodump → drop → mongorestore 实测)
备份(副本集连接串与 config.json 的 NODE_DB_URI 一致):
mongodump --uri 'mongodb://localhost:27017/habitica?replicaSet=rs&directConnection=true' --out /tmp/dump1
输出节选(实测):
2026-10-28T08:00:45.843+0000 done dumping `habitica.webhooks` (0 documents)
2026-10-28T08:00:45.843+0000 done dumping `habitica.tags` (0 documents)
2026-10-28T08:00:45.843+0000 done dumping `habitica.chats` (2 documents)
du -sh /tmp/dump1/habitica
108K /tmp/habitica 备份目录实测大小
(108K,含 users/tasks 等 9 个集合的 bson 与索引元数据。)演练完整恢复闭环——先记录基线、删库、再恢复、后验证:
mongosh --quiet --eval 'db.getSiblingDB("habitica").dropDatabase()'
{ ok: 1, dropped: 'habitica' }
mongosh --quiet --eval 'print(db.getSiblingDB("habitica").users.countDocuments({}))'
0
mongorestore --uri 'mongodb://localhost:27017/?replicaSet=rs&directConnection=true' /tmp/dump1
输出节选(实测):
2026-10-28T08:00:56.904+0000 9 document(s) restored successfully. 0 document(s) failed to restore.
mongosh --quiet --eval 'print("restored users:", db.getSiblingDB("habitica").users.countDocuments({}))'
restored users: 1
恢复后 API 侧端到端验证(原认证头直接可用,证明凭据与数据完整回归):
restore后 API: True habadmin
⚠️ 注意:
mongorestore的 URI 库名留空(restore 到 dump 内记录的原库名);备份计划建议每日 cron 执行 mongodump 并保留多份,恢复演练(drop → restore)务必先做一次完整备份。
七、Redis 运维:队列与键巡检
7.1 基本巡检
redis-cli ping
PONG
redis-cli info keyspace | head -4
(db0 的 keys 数量随运行时长增长,主要来自限流桶与会话数据。)
7.2 邮件队列(BullMQ)键族(实测)
触发一次密码重置后(POST /api/v4/user/reset-password,需 SESSION_SECRET_KEY 正确与 WORKER_REDIS_URL 已配,见配置详解篇 7.1/8.2 节),队列键族实测:
redis-cli --scan --pattern 'bull:emails:*' | sort
bull:emails:1
bull:emails:2
bull:emails:events
bull:emails:id
bull:emails:marker
bull:emails:meta
bull:emails:wait
redis-cli llen bull:emails:wait
1
wait 为待消费列表;单条任务本体是 hash(bull:emails:<id>),看任务类型与载荷:
redis-cli hget bull:emails:2 name
redis-cli --no-raw hget bull:emails:2 data | head -c 300
reset-password
{"emailType":"reset-password","to":[{"name":"habadmin","email":"admin@example.com",...}],"variables":[{"name":"BASE_URL","content":"http://10.89.71.10:3000"},{"name":"PASSWORD_RESET_LINK","content":"http://..."}]}
⚠️ 说明:自托管单机默认没有邮件 worker 消费该队列,任务会滞留(接口成功但邮件不发)。
llen bull:emails:wait即积压量监控点;积压属预期还是故障取决于是否部署了官方邮件 worker(配置详解篇第八节)。另有bull:DeleteUsers:*队列族承载账号删除任务。
八、参考链接
- 官方 API 文档(v3 全集,v4 为其超集):https://github.com/HabitRPG/habitica/wiki/API-Usage-Guide
- 源码脚本定义:v5.52.0 仓库
package.json(scripts)、gulpfile.js与gulp/目录 - 站内配套阅读:本专栏《Habitica 介绍与选型指南》(认知与选型篇)、《Ubuntu 22.04 安装 Habitica v5.52.0 指南》、《Habitica v5.52.0 配置参数详解》;同类 API 工具对照:《Beaver Habit Tracker v0.10.0 API 使用详解》、《OpenHabitTracker 1.2.5 API 使用详解》