Ubuntu 22.04 安装 Habitica v5.52.0 指南

Ubuntu 22.04 从零安装 Habitica v5.52.0 全流程实测:Node.js 20 + MongoDB 7.0 单节点副本集 + Redis 8 部署、前后端生产构建(vite+Babel 预转译)、最小配置集编排、systemd 托管与「最小配置三连崩」等真实排障。

HabiticaHabitica自托管2026/10/28

Ubuntu 22.04 安装 Habitica v5.52.0 指南

目标:在 Ubuntu 22.04 服务器上从零安装并运行 Habitica v5.52.0(游戏化习惯追踪应用),覆盖 Node.js 20 + MongoDB 7.0 单节点副本集 + Redis 8 三大依赖部署、源码获取、依赖安装、前后端生产构建、最小配置集编排、手动启动验证与 systemd 服务托管全流程,含「最小配置三连崩」等真实排障实录。已在 Ubuntu 22.04.5 LTS(x86_64)环境全量实测通过。

一、环境信息

本篇实测环境(一台干净的 Ubuntu 22.04 服务器,读者替换 IP 为自己的服务器地址):

  • 操作系统:Ubuntu 22.04.5 LTS(x86_64)
  • Habitica:v5.52.0(2026-10-26 发布的最新稳定版,git tag 获取)
  • Node.js:v20.20.2(NodeSource apt 源安装;源码 package.json 声明 engines: {"node": "20", "npm": "^10"},.nvmrc 亦为 20)
  • npm:v10.8.2
  • MongoDB:v7.0.45(MongoDB 官方 apt 仓库安装,必须配置为单节点副本集,见 4.4 节)
  • Redis:v8.10.3(官方 packages.redis.io apt 仓库安装)
  • 安装目录:/opt/habitica
  • 服务端口:3000(config.json PORT)
  • 站点访问 URL:http://10.89.71.10:3000(本机内网 IP,读者替换为自己的服务器 IP)
  • 运行用户:habitica(专用系统用户,非 root)
  • 系统资源:8 核 / 18GB 内存(单 worker 运行期 systemd 统计常驻约 160MB,见 4.10 节)
  • 演示账号:habadmin / q1w2e3r4(用户名 admin 会被平台保留词校验拦截,见 4.11 节排障实录)

二、前置条件

以下要求均来自官方仓库 v5.52.0 源码实查(package.json、.nvmrc、config.json.example、docker-compose.mongo-only.yml,查询日期 2026-10-28):

  1. Node.js 20:package.json 的 engines 字段精确声明 "node": "20"(非 >=20),仓库根 .nvmrc 同为 20——必须用 20.x 大版本,21/22 均可能触发依赖编译或运行时兼容问题;
  2. npm ^10:engines.npm = "^10",Ubuntu 22.04 自带 npm 8 不满足,随 NodeSource 一起升级;
  3. MongoDB 7.0 且为副本集模式:官方开发库连接串 mongodb://localhost:27017/habitica-dev?replicaSet=rs&directConnection=true,官方编排文件中 MongoDB 服务以 --replSet rs 参数启动并自动执行副本集初始化——单机 standalone 模式无法满足 Habitica 的事务与变更流需求,安装时必须显式配置;
  4. Redis:任务队列(BullMQ)与会话数据依赖 Redis,config.json.example 需要填 REDIS_HOST/REDIS_PORT/REDIS_PASSWORD;
  5. 构建资源:前端构建(vite)与后端 Babel 预转译内存峰值较高,建议至少 2GB 可用内存;本篇实测环境 18GB 未做 swap;
  6. 基础工具:curl、git、gnupg(添加软件源与拉取源码)。

确认系统版本的实测回显:

cat /etc/os-release | head -2
PRETTY_NAME="Ubuntu 22.04.5 LTS"
NAME="Ubuntu"
free -h | head -2
               total        used        free      shared  buff/cache   available
Mem:            17Gi       6.9Gi       3.2Gi       210Mi       7.4Gi        10Gi

三、版本选型说明

Habitica、Node.js、MongoDB、Redis 四者的版本对应关系是安装成败的第一道坎,本节给出实测选型依据(查询日期 2026-10-28):

组件实测安装版本选型依据
Habiticav5.52.0GitHub Releases 最新稳定版(2026-10-26 发布,releases.atom 实查)
Node.jsv20.20.2package.json engines: node "20" 与 .nvmrc: 20 双重实查,锁定 20.x 大版本
npmv10.8.2engines: npm "^10",随 NodeSource nodejs 包附带
MongoDBv7.0.45官方编排文件锁定 mongo:7.0 版本且要求副本集参数;7.0 为官方 apt 源在 22.04 可用的成熟大版本
Redisv8.10.3官方 packages.redis.io 仓库当前稳定版;Habitica 仅要求可用的 Redis 服务端

关键差异解读:Node.js 必须锁 20,这是本组件与多数 Node 系应用「engines 写 >= 下限」不同的地方——Habitica 把 engines 写成精确值 "20",意味着官方只对 20.x 做过兼容验证。MongoDB 的副本集要求是第二个易错点:用默认 standalone 配置启动后,应用能连上库但依赖副本集特性的写入路径会在运行期报错,必须在安装阶段一次性配好(见 4.4 节实测)。

版本获取命令(读者可随时复核最新版):

git ls-remote --tags https://github.com/HabitRPG/habitica.git | grep -oE 'v[0-9]+\.[0-9]+\.[0-9]+$' | sort -V | tail -3
v5.50.6
v5.51.0
v5.52.0

四、安装与部署(方案 A:在线源码安装)

4.1 安装基础依赖

sudo apt-get update
Hit:1 http://archive.ubuntu.com/ubuntu jammy InRelease
Reading package lists... Done
sudo apt-get install -y ca-certificates curl gnupg git

输出节选(实测):

Setting up git (1:2.34.1-1ubuntu1.15) ...
Processing triggers for ca-certificates (20240203~22.04.1) ...

4.2 安装 Node.js 20(NodeSource 源)

Habitica 要求 Node 20 精确大版本,走 NodeSource 的 20.x 分支仓库:

curl -fsSL https://deb.nodesource.com/setup_20.x -o /tmp/nodesource_setup.sh
sudo -E bash /tmp/nodesource_setup.sh

输出节选(实测):

2026-10-28 06:41:12 - Repository configured successfully.
To install Node.js, run: apt install nodejs -y
sudo apt-get install -y nodejs

输出节选(实测):

Setting up nodejs (20.20.2-1nodesource1) ...

验证版本(对照 engines 要求):

node -v && npm -v
v20.20.2
10.8.2

⚠️ 注意:不要用 setup_lts.x(跟随当前 LTS,2026-10 的 LTS 主线已是 24.x),Habitica engines 是精确值 "20",必须用 setup_20.x 锁定。

4.3 创建运行用户与目录

与官方多数 Node 系应用一样,Habitica 不需要 root 权限运行,本篇创建专用系统用户:

sudo useradd -m -s /bin/bash habitica
sudo mkdir -p /opt/habitica && sudo chown -R habitica:habitica /opt/habitica
id habitica
uid=1000(habitica) gid=1000(habitica) groups=1000(habitica)

4.4 安装 MongoDB 7.0 并配置单节点副本集

添加 MongoDB 官方 GPG 密钥与 apt 源(Ubuntu 22.04 对应 jammy):

curl -fsSL https://www.mongodb.org/static/pgp/server-7.0.asc | \
  sudo gpg -o /usr/share/keyrings/mongodb-server-7.0.gpg --dearmor
echo "deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse" | \
  sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.list
deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse
sudo apt-get update && sudo apt-get install -y mongodb-org

输出节选(实测):

Setting up mongodb-org-database (7.0.45) ...
Setting up mongodb-org (7.0.45) ...
mongod --version | head -3
db version v7.0.45
Build Info: {
    "version": "7.0.45",

配置副本集(本节为 Habitica 特有必做项):编辑 /etc/mongod.conf,在文件末尾追加:

replication:
  replSetName: rs

重启 mongod 并初始化副本集(单节点副本集只需 initiate 一次):

sudo systemctl restart mongod && systemctl is-active mongod
active
mongosh --quiet --eval 'rs.initiate()'
{ ok: 1 }

验证副本集角色(应看到 PRIMARY):

mongosh --quiet --eval 'rs.status().members.map(m => m.name + ": " + m.stateStr)'
[ '127.0.0.1:27017: PRIMARY' ]
sudo systemctl enable --now mongod
Synchronizing state of mongod.service with SysV service script with /usr/lib/systemd/systemd-sysv-install.

⚠️ 排障实录:若跳过 rs.initiate(),rs.status() 会报 MongoServerError: no replset config has been received;应用侧连接串中的 replicaSet=rs 参数将始终无法就绪,启动日志停留在 MongoDB 等待状态。rs.initiate() 只需在首次配置后执行一次,mongod 重启后副本集配置持久保存在数据目录中。

4.5 安装 Redis

添加 Redis 官方 apt 仓库(Ubuntu 自带源版本较老,仅作缓存用途亦够用,但建议官方源):

curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb jammy main" | \
  sudo tee /etc/apt/sources.list.d/redis.list
sudo apt-get update && sudo apt-get install -y redis

输出节选(实测):

Setting up redis-server (8:8.10.3-1rl1~jammy1) ...
sudo systemctl enable --now redis-server && systemctl is-active redis-server
Synchronizing state of redis-server.service with SysV service script with /usr/lib/systemd/systemd-sysv-install.
active
redis-cli ping
PONG

💡 说明:本机 Redis 未设密码,后续 config.json 中 REDIS_PASSWORD 留空即可(Habitica 的 Redis 客户端仅在密码非空时发送 AUTH)。若为生产环境建议启用 requirepass 并同步填写 REDIS_PASSWORD。

4.6 获取 Habitica 源码(git 方式)

sudo -u habitica git clone --depth 1 -b v5.52.0 https://github.com/HabitRPG/habitica.git /opt/habitica

输出节选(实测):

Cloning into '/opt/habitica'...
Note: switching to 'v5.52.0'.
You are in 'detached HEAD' state...

确认版本与入口文件:

cd /opt/habitica && git log --oneline -1
12091ca02990533fdf38c2f0947397f0b4e39d59 (grafted, HEAD -> tag: v5.52.0) Release v5.52.0 - 2026-10-26
ls /opt/habitica/website/server/index.js /opt/habitica/config.json.example /opt/habitica/Procfile
/opt/habitica/Procfile
/opt/habitica/config.json.example
/opt/habitica/website/server/index.js

💡 说明:仓库根的 Procfile 内容为 web: node ./website/transpiled-babel/index.js——这揭示了 Habitica 的生产启动约定:生产模式运行的是 Babel 预转译产物 website/transpiled-babel/,而不是源码目录 website/server/。开发模式下(NODE_ENV 非 production)入口 index.js 会动态挂载 @babel/register 实时转译;生产模式为性能考虑要求预转译(见 4.8 节构建步骤)。这是与多数「克隆即运行」Node 应用的最大差异。

4.7 安装依赖(npm ci)

以 habitica 用户执行完整依赖安装(根目录服务端依赖 + postinstall 钩子会自动进入 website/client 安装前端依赖,整体耗时约 10 分钟):

cd /opt/habitica && sudo -u habitica npm ci --no-audit --no-fund

输出节选(实测,服务端依赖在前端依赖之前):

added 737 packages, and audited 738 packages in 3m

postinstall 钩子自动完成的动作(源码 package.json postinstall 脚本实查:git config --global url."https://".insteadOf git:// && gulp build && cd website/client && npm install):

> habitica@5.52.0 postinstall
> git config --global url."https://".insteadOf git:// && gulp build && cd website/client && npm install

added 1928 packages in 7m

逐段解读:第一条 git config 把仓库内的 git:// 协议依赖改写为 https://(避免 GitHub 已停用的 git 协议导致安装失败);gulp build 在非生产模式下仅执行开发准备任务(Linux 上为空操作);cd website/client && npm install 安装前端依赖(1928 包)。

验证两侧依赖安装完整:

ls /opt/habitica/node_modules | wc -l && ls /opt/habitica/website/client/node_modules | wc -l
1129
480

⚠️ 排障实录:依赖安装阶段曾出现大量 npm warn deprecated 提示(bootstrap 4.6.2、vue 2.7.16、popper.js 等),均为上游依赖的版本提示,不阻断安装,等待 added xxx packages 出现即可。若在 git 协议上卡住(git://github.com/... 连接超时),说明 postinstall 的 git config insteadOf 未生效,可手工执行一次 git config --global url."https://".insteadOf git:// 后重跑 npm ci。

4.8 生产构建(前端 vite + 后端 Babel 预转译)

生产运行需要两个构建产物:前端静态资源(website/client/dist/)与后端 Babel 预转译代码(website/transpiled-babel/)。

第一步,构建前端(vite,实测 8.74 秒,产物约 93MB):

cd /opt/habitica && sudo -u habitica npm run client:build

输出节选(实测):

> habitica@5.52.0 client:build
> cd website/client && npm run build

vite v6.4.1 building for production...
transforming...
rendering chunks...
dist/compressed/stickermule-logo.svg     2.48 kB
dist/compressed/teespring-logo.svg       2.74 kB
✓ built in 8.74s
du -sh /opt/habitica/website/client/dist
93M	/opt/habitica/website/client/dist

第二步,后端 Babel 预转译 + 内容缓存(必须带 NODE_ENV=production,实测 7.16 秒):

cd /opt/habitica && sudo -u habitica env NODE_ENV=production npx gulp build:prod

输出节选(实测):

[07:31:35] Starting 'build:babel:server'...
[07:31:35] Starting 'build:babel:common'...
[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

验证两个产物目录:

ls -d /opt/habitica/website/transpiled-babel /opt/habitica/website/common/transpiled-babel && ls /opt/habitica/website/transpiled-babel | head -5
/opt/habitica/website/common/transpiled-babel
/opt/habitica/website/transpiled-babel
api-doc.js
controllers
index.js
libs
middlewares

⚠️ 排障实录:npm run client:build 若报 JavaScript 堆内存耗尽(FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory),是小内存机器 vite 构建的典型症状,可在命令前加 NODE_OPTIONS=--max-old-space-size=4096 提高堆上限;本篇实测环境 18GB 内存未触发。另外 gulp build:prod 不带 NODE_ENV=production 时会走开发分支(gulpfile.js 按 NODE_ENV 选择 build:prod 或 build:dev),不会产出 transpiled-babel 目录,生产部署务必显式携带环境变量。

4.9 编写 config.json(最小可运行集)

从示例配置复制后按最小集改写。Habitica 的启动崩溃点集中在「模块加载期读取的键」,以下最小集为实测通过版本:

cd /opt/habitica && sudo -u habitica cp config.json.example config.json

实测使用的最小可运行 config.json(逐项说明见本专栏配置详解篇):

{
  "PORT": 3000,
  "NODE_ENV": "production",
  "BASE_URL": "http://10.89.71.10:3000",
  "NODE_DB_URI": "mongodb://localhost:27017/habitica?replicaSet=rs&directConnection=true",
  "TEST_DB_URI": "mongodb://localhost:27017/habitica-test?replicaSet=rs&directConnection=true",
  "MONGODB_POOL_SIZE": "10",
  "REDIS_HOST": "127.0.0.1",
  "REDIS_PORT": "6379",
  "REDIS_PASSWORD": "",
  "WORKER_REDIS_URL": "redis://127.0.0.1:6379",
  "SESSION_SECRET": "habitica-lab-session-secret-2026",
  "SESSION_SECRET_KEY": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
  "WEB_CONCURRENCY": 1,
  "EMAIL_SERVER_URL": "http://127.0.0.1:9263",
  "EMAIL_SERVER_AUTH_USER": "admin",
  "EMAIL_SERVER_AUTH_PASSWORD": "q1w2e3r4",
  "ADMIN_EMAIL": "admin@example.com",
  "FLAG_REPORT_EMAIL": "admin@example.com",
  "MAINTENANCE_MODE": "false",
  "CRON_SAFE_MODE": "false",
  "CRON_SEMI_SAFE_MODE": "false",
  "RATE_LIMITER_ENABLED": "false",
  "DISABLE_REQUEST_LOGGING": "true",
  "IGNORE_REDIRECT": "false",
  "PAYPAL_MODE": "sandbox",
  "PAYPAL_CLIENT_ID": "sandbox-client-id",
  "PAYPAL_CLIENT_SECRET": "sandbox-client-secret",
  "GOOGLE_CLIENT_ID": "123456789012345",
  "GOOGLE_CLIENT_SECRET": "aaaabbbbccccddddeeeeffff00001111"
}
sudo chown habitica:habitica /opt/habitica/config.json

⚠️ 排障实录(最小配置三连崩,均为本篇首次启动时逐个实测命中的真实错误):

崩溃一——缺 PAYPAL_MODE:worker 进程启动即抛 Error: Mode must be "sandbox" or "live"(node_modules/paypal-rest-sdk 的 configure() 直接 throw),因主进程 cluster 机制不断重拉 worker,日志反复出现 worker:xxxx disconnect! new worker:yyyy fork。补 PAYPAL_MODE: "sandbox"(客户端密钥可先用占位值)后消失。

崩溃二——缺 FLAG_REPORT_EMAIL:worker 抛 TypeError: Cannot read properties of undefined (reading 'split'),出错文件 libs/challenges/reporting.js:16——该模块在加载期对 nconf.get('FLAG_REPORT_EMAIL') 直接调用 .split(',')。补任意邮箱值后消失。

崩溃三——缺 GOOGLE_CLIENT_ID/GOOGLE_CLIENT_SECRET:worker 抛 passport 构造异常(passport-google-oauth20/lib/strategy.js:52 的 new Strategy({clientID: undefined, ...}),libs/setupPassport.js:16 加载期注册 OAuth 策略)。补占位值后消失。

三处均为模块加载期硬读取,任何一处缺失都会让 worker 反复崩溃重启,且日志被 winston 默认「无 transports」配置吞掉大部分细节,极易误判为依赖问题。安装阶段建议直接采用上方实测最小集。

4.10 手动启动验证

先以命令行前台方式验证配置正确(观察是否有 worker 崩溃循环),再交给 systemd:

cd /opt/habitica && sudo -u habitica env NODE_ENV=production node website/transpiled-babel/index.js

启动成功后服务进入监听状态(日志安静即正常——生产模式默认无控制台日志输出,ENABLE_CONSOLE_LOGS_IN_PROD=false 所致)。另开终端验证:

curl -s -o /dev/null -w 'HTTP:%{http_code}\n' http://10.89.71.10:3000/
HTTP:200
curl -s http://10.89.71.10:3000/ | grep -oE "<title>[^<]*</title>"
<title>Habitica - Gamify Your Life</title>
curl -s http://10.89.71.10:3000/api/v3/status
{"success":true,"data":{"status":"up"},"appVersion":"5.52.0"}

浏览器访问 http://10.89.71.10:3000 进入 Habitica 首页,点击右上角 Register 注册首个账号(用户名规则见下节排障实录)。验证通过后 Ctrl+C 停止前台进程,进入 systemd 托管。

⚠️ 注意:若此处用 http://127.0.0.1:3000 访问首页会收到 301 Moved Permanently 并跳转到 BASE_URL——这是生产模式下 middlewares/redirects.js 的 forceHabitica 中间件行为(对非 API 的 GET 请求强制重定向到 BASE_URL 主机名),属预期行为而非故障;API 路径(/api/ 前缀)与非 GET 请求不受影响。详见本专栏配置详解篇。

4.11 注册首个账号(排障实录:保留词用户名)

在 Web 页面或直接调 API 注册首个账号。实测用 admin 作为用户名会被拒绝:

curl -s -X POST http://10.89.71.10:3000/api/v4/user/auth/local/register \
  -H 'Content-Type: application/json' \
  -d '{"username":"admin","password":"q1w2e3r4","email":"admin@example.com","confirmPassword":"q1w2e3r4"}'
{"success":false,"error":"BadRequest","message":"Usernames may not contain restricted words."}

原因:Habitica 服务端有保留词库 website/server/libs/bannedWords.js,admin 在列;校验用整词边界正则(libs/user/validation.js:11,\\badmin\\b),因此 habadmin 这类包含 admin 字样但非独立单词的名称可以通过:

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}, ...

💡 生产建议:正式环境请使用强口令(大小写+数字+符号 12 位以上),本篇为演示统一使用 q1w2e3r4。

4.12 systemd 服务托管

创建 /etc/systemd/system/habitica-web.service:

[Unit]
Description=Habitica Web Server
After=network.target mongod.service redis-server.service
Wants=mongod.service redis-server.service

[Service]
Type=simple
User=habitica
Group=habitica
WorkingDirectory=/opt/habitica
Environment=NODE_ENV=production
ExecStart=/usr/bin/node /opt/habitica/website/transpiled-babel/index.js
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

逐项说明:After/Wants 保证 MongoDB 与 Redis 先于应用启动;User=habitica 以非特权用户运行;Environment=NODE_ENV=production 是关键项——生产入口 index.js 以 process.env.NODE_ENV !== 'production' 判断是否挂载 @babel/register,同时 nconf 据此计算 IS_PROD 开启生产中间件链;ExecStart 指向预转译产物(与官方 Procfile 一致);Restart=always 崩溃后 5 秒拉起。

启用并启动:

sudo systemctl daemon-reload
sudo systemctl enable --now habitica-web
Created symlink /etc/systemd/system/multi-user.target.wants/habitica-web.service → /etc/systemd/system/habitica-web.service.
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

进程树显示 1 个主进程 + 1 个 worker(WEB_CONCURRENCY=1 时主进程 fork 1 个 worker 承载 HTTP 流量,主进程仅负责监控重拉)。最终验证:

curl -s -o /dev/null -w 'Web HTTP:%{http_code}\n' http://10.89.71.10:3000/ && \
curl -s http://10.89.71.10:3000/api/v4/status
Web HTTP:200
{"success":true,"data":{"status":"up"},"appVersion":"5.52.0"}

💡 说明:systemd 托管下 journalctl -u habitica-web 默认几乎看不到应用日志——生产模式 winston 无 Console transport(ENABLE_CONSOLE_LOGS_IN_PROD=false 默认关闭)。排障时可在单元文件追加 Environment=ENABLE_CONSOLE_LOGS_IN_PROD=true 后 systemctl daemon-reload && systemctl restart habitica-web 临时开启。日常运维命令详见本专栏 CLI 命令详解篇。

五、方案 B:弱网环境要点(tarball 与 npm 镜像)

与方案 A 的差异仅在「源码与依赖获取渠道」:源码可用官方 tag tarball 直链(codeload.github.com)下载后解压到 /opt/habitica,npm 依赖可切换国内镜像源加速。适用于服务器不便直连 GitHub 的场景。

curl -L -o /tmp/habitica.tar.gz https://codeload.github.com/HabitRPG/habitica/tar.gz/refs/tags/v5.52.0
tar xzf /tmp/habitica.tar.gz -C /opt/ && sudo mv /opt/habitica-5.52.0 /opt/habitica && sudo chown -R habitica:habitica /opt/habitica

npm 镜像源加速(先验证镜像连通性):

npm ping --registry=https://registry.npmmirror.com
npm notice PONG
cd /opt/habitica && sudo -u habitica npm ci --no-audit --no-fund --registry=https://registry.npmmirror.com

⚠️ 注意:npm ci 严格按 package-lock.json 锁定版本安装,--registry 仅替换下载渠道、不改变版本;postinstall 中进入 website/client 的子安装同样继承该 registry。后续生产构建(4.8 节)、config.json(4.9 节)、systemd 托管(4.12 节)与方案 A 完全一致,不再重复。本篇实测环境可直连官方源,以上镜像源命令仅验证连通性后未再实际启用。

六、常见问题(FAQ)

Q1:启动后服务反复重启,日志里 worker:xxxx disconnect! new worker:yyyy fork 循环出现? worker 崩溃后主进程 cluster 机制自动重拉的表现。根因几乎都是 config.json 缺少模块加载期硬读取的键(PAYPAL_MODE、FLAG_REPORT_EMAIL、GOOGLE_CLIENT_ID/SECRET 三处实测确认),按 4.9 节最小集补齐即可。临时开启 ENABLE_CONSOLE_LOGS_IN_PROD=true 可看到完整堆栈。

Q2:rs.status() 报 no replset config has been received? 副本集未初始化。/etc/mongod.conf 配置 replication.replSetName: rs 并重启后,执行一次 mongosh --eval 'rs.initiate()'(见 4.4 节)。

Q3:npm run client:build 阶段 OOM? vite 构建内存峰值高,小内存机器加 NODE_OPTIONS=--max-old-space-size=4096,或临时关闭其他占内存服务(见 4.8 节排障实录)。

Q4:访问 http://127.0.0.1:3000/ 返回 301 跳走? 生产模式 BASE_URL 强制重定向中间件所致(仅重定向非 API 的 GET 请求)。用 BASE_URL 中配置的地址访问即可;内网调试可临时设 IGNORE_REDIRECT: "true" 关闭(详见配置详解篇实测)。

Q5:注册用户名报 Usernames may not contain restricted words.? 用户名 admin/root 等在保留词库中被整词拦截(4.11 节实测),换 habadmin 类非独立词即可。

Q6:密码重置等邮件功能接口返回 500? 邮件走 BullMQ 队列异步投递:config.json 缺 WORKER_REDIS_URL 时队列未创建会直接 500;另注意 SESSION_SECRET_KEY 必须是 64 位十六进制字符串(AES-256-GCM 密钥按 hex 解码,非 hex 值会让加密环节抛错返回 500)。两类问题均在本专栏配置详解篇有实测复现与修复记录。

Q7:git clone 或依赖安装阶段卡在 git:// 协议超时? 重跑 postinstall 的第一条命令:git config --global url."https://".insteadOf git://,再重新 npm ci(见 4.7 节)。

七、卸载与清理

停止服务并移除 systemd 单元:

sudo systemctl disable --now habitica-web
Removed "/etc/systemd/system/multi-user.target.wants/habitica-web.service".
sudo rm /etc/systemd/system/habitica-web.service && sudo systemctl daemon-reload

删除程序目录与运行用户(数据库备份确认不再需要后执行):

sudo rm -rf /opt/habitica /home/habitica

删除应用数据库:

mongosh --quiet --eval 'db.getSiblingDB("habitica").dropDatabase()'
{ ok: 1, dropped: 'habitica' }

如需彻底移除 MongoDB 与 Redis(Node.js 可保留):

sudo apt-get purge -y mongodb-org* redis-server && sudo rm -rf /var/lib/mongodb /var/log/mongodb /etc/apt/sources.list.d/mongodb-org-7.0.list /etc/apt/sources.list.d/redis.list

八、参考链接