4ga Boards 3.3.13 常用 CLI 命令与工具详解
4ga Boards v3.3.13 常用命令与工具详解:systemd 服务管理、db:init 幂等/迁移回滚重应用/种子冲突实测、sails console 换端口实测、pnpm 构建与 npm EBADDEVENGINES 实测、pg_dump+tar 备份恢复全流程演练、API 诊断命令(2026-10-22 实测)。
4ga Boards 3.3.13 常用 CLI 命令与工具详解
目标:整理 4ga Boards v3.3.13 日常运维所需的全部命令与工具——服务进程管理、数据库初始化/迁移/种子、交互式控制台、前端构建、备份恢复、API 诊断,每条命令附真实执行回显。命令定义实查自 v3.3.13 源码
package.json与官方脚本,回显采集于 2026-10-22 的实测环境。安装方法见 《Ubuntu 22.04 安装 4ga Boards 3.3.13 指南》(源码手动安装)与 《4ga Boards 3.3.13 Docker Compose 部署指南》(容器编排),参数说明见 《4ga Boards 3.3.13 配置参数详解》。
一、环境信息
本文命令在以下两个现场实测:
现场 A:源码手动安装(主现场)
- 系统:Ubuntu 22.04(x86_64)
- 运行时:Node.js v24.22.1 + pnpm 11.28.7
- 数据库:PostgreSQL 14.24(本机 5432,库
4gaBoards,应用账号boards) - 源码目录:
/opt/4gaBoards/src(tag v3.3.13,commit bff02e86954db545c0bb5835bbdea7cdf7740695) - 服务托管:systemd 单元
4gaboards(User=boards,ExecStart=/opt/4gaBoards/src/server/start.sh),应用监听127.0.0.1:1337 - 服务端环境:
/opt/4gaBoards/src/server/.env(BASE_URL=http://localhost:1337、DATABASE_URL=postgresql://boards:***@localhost:5432/4gaBoards) - 初始账号:
.env未覆盖DEFAULT_ADMIN_*,首建账号为官方默认demo/demo
现场 B:Docker Compose(辅助现场)
- 应用容器(
ghcr.io/rargames/4gaboards:3.3.13,监听映射 8132)+ PostgreSQL 18 + Redis 8,项目名4ga-boards-3313-stack - 初始账号:compose 显式覆盖为
admin/q1w2e3r4
二、工具概览
4ga Boards 没有独立的 CLI 二进制,命令面由五部分组成:
| 命令面 | 位置 | 用途 | 本文章节 |
|---|---|---|---|
| systemd 服务管理 | 系统层 | 启停/状态/日志 | 4.1 |
| server npm scripts | src/server/ | 数据库初始化、迁移、种子、控制台 | 4.2–4.4 |
| root pnpm scripts | src/ | 前端/依赖包构建、测试 | 4.5 |
| 官方备份/恢复脚本 | 源码仓库根目录 boards-backup.sh、boards-restore.sh | 容器部署的一键备份恢复(源码部署用 4.6 的 pg_dump 流程) | 4.6 |
| HTTP API + curl | 应用端口 | 健康诊断、账号核验 | 4.7 |
server 目录脚本定义(实查 src/server/package.json):
"scripts": {
"console": "dotenv sails console",
"db:init": "node db/init.js",
"db:migrate": "knex migrate:latest --cwd db",
"db:rollback_one": "knex migrate:down --cwd db",
"db:rollback": "knex migrate:rollback --cwd db",
"db:migration_make": "knex migrate:make new_migration --cwd db",
"db:seed": "knex seed:run --cwd db",
"start:prod": "node app.js --prod"
}
其中 start.sh(服务启动入口)由两行构成——数据库初始化内置于每次启动:
#!/bin/bash
set -e
node db/init.js
exec node app.js --prod $@
三、前置条件
- 一套按上述方式部署并运行中的 v3.3.13 实例;
- 源码现场需能以部署用户(本文
boards/root)执行cd /opt/4gaBoards/src/server; - 数据库命令需要
DATABASE_URL指向的账号具备相应权限(迁移/种子需建表写数据,备份导出用只读也够); pg_dump/pg_restore等客户端工具由 PostgreSQL 服务端安装包自带(sudo apt install postgresql-client可单独补装)。
四、各工具详解
4.1 服务进程管理(systemd)
服务日常管理(现场 A,需 root):
systemctl status 4gaboards --no-pager
输出(正常运行态):
● 4gaboards.service - 4ga Boards service
Loaded: loaded (/etc/systemd/system/4gaboards.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2026-10-22 16:27:10 UTC; 30min ago
Main PID: 7403 (start.sh)
Tasks: 12 (limit: 4519)
Memory: 229.5M
CPU: 8.918s
CGroup: /system.slice/4gaboards.service
启停与重启:
sudo systemctl start 4gaboards # 启动
sudo systemctl stop 4gaboards # 停止
sudo systemctl restart 4gaboards # 重启(改 .env 后必须执行)
sudo systemctl enable 4gaboards # 开机自启(安装时已做,此处为补查命令)
查服务日志(应用日志同时写 src/server/logs/4gaBoards.log):
journalctl -u 4gaboards -n 5 --no-pager
输出(启动成功后):
Oct 22 16:27:10 4gaboards-server start.sh[7403]: 16:27:10 [INFO] 4ga Boards lifted successfully!
Oct 22 16:27:10 4gaboards-server start.sh[7403]: 16:27:10 [INFO] SystemNotifications: Registering instance (instanceId: 72e302ec-fd1e-46b5-8ccd-acefb7336da3)...
Oct 22 16:27:11 4gaboards-server start.sh[7403]: 16:27:11 [INFO] SystemNotifications: Registered successfully
4ga Boards lifted successfully! 是启动成功的标志行;启动失败时此行不出现且 systemctl is-active 为 failed。
4.2 数据库初始化与迁移(server npm scripts)
node db/init.js(初始化,幂等)——首次建库跑全部迁移+种子,已有库直接跳过。对已初始化的库重跑:
cd /opt/4gaBoards/src/server
node db/init.js
echo "exit=$?"
输出:
exit=0
无任何输出、退出码 0 即为幂等成功,可放心重跑(这也是 start.sh 每次启动都执行它的原因)。
npm run db:migrate(应用全部未执行迁移)——已是最新时:
cd /opt/4gaBoards/src/server
npm run db:migrate --silent
输出:
Already up to date
npm run db:rollback_one(回滚最近一批的一个迁移):
npm run db:rollback_one --silent
输出(实测,回滚了当时迁移列表的最后一个):
Batch 1 rolled back the following migrations:
20260704201223_add_suppressed_system_notification_tags_and_show_full_due_dates_to_user_prefs.js
随即重新应用恢复:
npm run db:migrate --silent
输出:
Batch 2 run: 1 migrations
⚠️ 生产库执行 rollback 前必须先备份(4.6 节)。回滚只动 schema 不动业务数据,但降级版本时 schema 不兼容会直接伤数据——优先用备份恢复回退。
npm run db:migration_make(生成迁移骨架文件):
npm run db:migration_make --silent
输出:
Created Migration: /opt/4gaBoards/src/server/db/migrations/20261022165359_new_migration.js
生成的文件名前缀是时间戳、后缀固定 new_migration(脚本内置名)。实测后已删除该文件,不残留到业务库。
迁移记录表:迁移状态存于库中 migration 表(db/knexfile.js 自定义 tableName: 'migration',不是 knex 默认的 knex_migrations)——直查迁移历史时注意表名:
su postgres -c "psql -d 4gaBoards -c \"select count(*) from migration;\""
4.3 种子命令(npm run db:seed)
种子脚本 db/seeds/default.js 创建初始管理员并写入实例级开关(注册开关等)。它仅供首次建库(db/init.js 在迁移表不存在时自动调用),手动重跑会因唯一约束报错——实测:
npm run db:seed
输出(核心报错行):
Error: Error while executing "/opt/4gaBoards/src/server/db/seeds/default.js" seed: insert into "user_account" ("created_at", "created_by_id", "email", "is_admin", "name", "password", "username") values ($1, $2, $3, $4, $5, $6, $7) returning "id" - conflicting key value violates exclusion constraint "user_email_unique"
结论:已有用户的库不要跑 db:seed;新增管理员走界面(管理员账号的「+ 新用户」)或管理员 API。
4.4 交互式控制台(npm run console)
sails console 启动一个挂在完整应用上下文里的 Node REPL,可查询/调试运行时配置与数据,排障与数据修复利器。注意它会占用应用端口:服务运行中直接启动会报端口冲突——实测:
npm run console --silent
输出(1337 被占用时):
16:54:23 [ERROR] error: -> Is something else already running on port 1337 ?
规避:换端口启动 console(PORT 环境变量对 console 同样生效),不影响正在运行的服务:
printf "sails.config.custom.tokenExpiresIn\n" | PORT=1338 npm run console --silent 2>&1 | tail -5
输出(实测,REPL 中执行查询):
info: Welcome to the Sails console.
info: ( to exit, type <CTRL>+<C> )
sails> sails.config.custom.tokenExpiresIn
365
sails>
console 中查询
sails.config.custom.tokenExpiresIn返回365,与 JWT 实测有效期 365 天(见 《4ga Boards 3.3.13 配置参数详解》 6.1 节)三方印证。交互式使用时输入 JS 表达式回车执行,Ctrl+C退出;只读查询用管道方式(如上)最安全。
4.5 构建命令(root pnpm scripts)
前端与共享包构建在源码根目录执行。必须用 pnpm:根 package.json 的 devEngines 强制包管理器为 pnpm,用 npm 会直接报错——实测:
cd /opt/4gaBoards/src
npm run client:build
输出:
npm error code EBADDEVENGINES
npm error EBADDEVENGINES The developer of this package has specified the following through devEngines
npm error EBADDEVENGINES Invalid devEngines.packageManager
npm error EBADDEVENGINES Invalid name "pnpm" does not match "npm" for "packageManager"
改用 pnpm(升级前后端产物,pnpm run client:build 单独构建前端):
pnpm run client:build > /tmp/cbuild.log 2>&1; echo "exit=$?"
tail -12 /tmp/cbuild.log
输出:
exit=0
7.75 kB build/static/js/764.6835b60a.chunk.js
5.13 kB build/workbox-1425c628.js
2.04 kB build/static/js/runtime.02958446.js
Total (gzip): 1.56 MB
The bundle size is significantly larger than recommended. Consider reducing it with code splitting.
You can also analyze the project dependencies using: `pnpm client:build --stats` and `pnpm dlx webpack-bundle-analyzer client/build/bundle-stats.json`
The project was built assuming it is hosted at BASE_URL_PLACEHOLDER.
The build folder is ready to be deployed.
构建产物在
src/client/build/,前端以BASE_URL_PLACEHOLDER占位编译,运行时由服务端按BASE_URL动态替换。server:start:prod(=node app.js --prod)是start.sh第二行的等价命令,一般不单独执行。
常用 root scripts 一览(pnpm run <名称>,均在 src/ 执行):
| 命令 | 作用 |
|---|---|
packages:build | 构建共享依赖包(前端构建的前置) |
client:build | 构建前端(生产部署必跑) |
client:start / server:start | 开发模式启动前端/后端 |
test | 服务端 + 客户端全部测试 |
test:e2e | 端到端测试(需 pnpm start 运行中的应用) |
lint | 全仓 lint |
4.6 备份与恢复
源码部署(现场 A 实测全流程):需要备份的是 PostgreSQL 数据库 + 三个上传文件目录(附件/头像/项目背景图)。
备份:
TS=$(date +%Y%m%d-%H%M%S)
mkdir -p /opt/4gaBoards/backup
echo "== 备份数据库 =="
PGPASSWORD=q1w2e3r4 pg_dump -h localhost -U boards 4gaBoards | gzip > /opt/4gaBoards/backup/db-4gaBoards-$TS.sql.gz
ls -lh /opt/4gaBoards/backup/db-4gaBoards-$TS.sql.gz
echo "== 备份上传文件目录 =="
tar -czf /opt/4gaBoards/backup/files-$TS.tar.gz -C /opt/4gaBoards/src/server private/attachments public/user-avatars public/project-background-images
ls -lh /opt/4gaBoards/backup/files-$TS.tar.gz
输出(空库新装实例,数据量小):
== 备份数据库 ==
-rw-r--r-- 1 root root 9.2K Oct 22 16:56 backup/db-4gaBoards-20261022-165626.sql.gz
== 备份上传文件目录 ==
-rw-r--r-- 1 root root 237 Oct 22 16:56 backup/files-20261022-165626.tar.gz
恢复(实测演练:删库→重建→灌回→验证):
TS=$(cat /tmp/backup-ts)
echo "== 恢复演练:删库重建 =="
su postgres -c "dropdb 4gaBoards && createdb -O boards 4gaBoards"
echo "== 恢复数据库 =="
gunzip -c /opt/4gaBoards/backup/db-4gaBoards-$TS.sql.gz | su postgres -c "psql -d 4gaBoards -q"
echo "== 恢复文件目录 =="
tar -xzf /opt/4gaBoards/backup/files-$TS.tar.gz -C /opt/4gaBoards/src/server
echo "== 重启服务 =="
systemctl restart 4gaboards
输出:
== 恢复演练:删库重建 ==
== 恢复数据库 ==
== 恢复文件目录 ==
== 重启服务 ==
验证(恢复后登录与首页均正常):
curl -s -o /dev/null -w "恢复后登录 HTTP %{http_code}\n" -X POST http://localhost:1337/api/access-tokens -H "Content-Type: application/json" -d '{"emailOrUsername":"demo","password":"demo"}'
curl -s -o /dev/null -w "恢复后首页 HTTP %{http_code}\n" http://localhost:1337/
输出:
恢复后登录 HTTP 200
恢复后首页 HTTP 200
pg_dump导出为纯 SQL(含OWNER TO boards),以 postgres 超级用户灌回后属主自动归位;-q静默模式只输出错误。生产建议把备份目录纳入定时任务并异机存放。
Compose 部署:用官方脚本 boards-backup.sh / boards-restore.sh(源码仓库根目录,按「Compose 工作目录名小写」推导容器名,含卷与数据库全量打包)。获取与完整用法、真实回显见 《4ga Boards 3.3.13 Docker Compose 部署指南》第五章(含目录命名与容器前缀匹配的注意事项)。核心用法:
sudo ./boards-backup.sh # 产出 4gaBoards-backup-<时间戳>.tgz
sudo ./boards-restore.sh 4gaBoards-backup-<时间戳>.tgz
4.7 API 诊断(curl)
登录取令牌并核验当前账号(适用于脚本化巡检):
UIDemo=$(curl -s -X POST http://localhost:1337/api/access-tokens -H "Content-Type: application/json" -d '{"emailOrUsername":"demo","password":"demo"}' | python3 -c "import sys,json;print(json.load(sys.stdin)[\"item\"])")
curl -s -w "\nHTTP %{http_code}\n" -H "Authorization: Bearer $UIDemo" http://localhost:1337/api/users/1891585550805107718 | head -c 400
输出(item 为登录返回的 JWT;用户 ID 取自本实例实测):
{"item":{"id":"1891585550805107718","createdAt":"2026-10-22T16:22:49.000Z","updatedAt":null,"email":"demo@demo.demo","isAdmin":true,"isVerified":false,"name":"Demo Demo","username":"demo","phone":null,"organization":null,"ssoGoogleEmail":null,"ssoGithubUsername":null,"ssoGithubEmail":null,"ssoMicrosoftEmail":null,"ssoOidcEmail":null,"lastLogin":null,"lastEmailVerificationRequestAt":null,"deletedAt
要点:
- 登录端点
POST /api/access-tokens,请求体{"emailOrUsername":"...","password":"..."},响应{"item":"<JWT>"}; - 带
Authorization: Bearer <JWT>访问资源端点(如GET /api/users/<id>); - 连续登录失败会触发限流(默认 60 秒窗口 5 次,返回 429),巡检脚本勿用错误密码重试(限流实测见 《4ga Boards 3.3.13 配置参数详解》 6.2 节);
- 无需认证的探活:
curl -s -o /dev/null -w '%{http_code}' http://localhost:1337/返回 200 即服务可响应。
五、注意事项
db:seed不可对已有库执行(4.3 节实测报唯一约束冲突),首建类参数只在全新库生效;- 根目录构建命令必须用 pnpm(4.5 节实测 npm 报
EBADDEVENGINES),server 目录的 npm scripts 无此限制; - 迁移操作前先备份:
db:rollback*只回 schema,但一旦与数据版本不匹配,恢复手段只剩备份;应用每次启动经start.sh自动db:init(迁移到最新),因此升级应用后无需手动跑迁移; - console 会抢端口:运行中的服务占着 1337,console 用
PORT=1338 npm run console换端口进入(4.4 节实测); 4ga Boards lifted successfully!是启动成功标志,systemd 巡检可journalctl -u 4gaboards -n 50 | grep lifted快速确认最近一次启动结果;- 备份须同时覆盖数据库与三个上传目录(附件/头像/背景图),只备库会丢附件。
六、常见问题
Q1:systemctl restart 4gaboards 后服务起不来,怎么定位?
按顺序看三处:systemctl status 4gaboards --no-pager(进程态)→ journalctl -u 4gaboards -n 50 --no-pager(启动日志,常见为 DATABASE_URL 连不上或 BASE_URL 缺失)→ 端口占用 ss -tlnp | grep 1337。配置项排查见 《4ga Boards 3.3.13 配置参数详解》 第五章。
Q2:npm run console 报 "Is something else already running on port 1337?"
服务正在运行占用了端口,console 也要 lift 应用。用 PORT=1338 npm run console 换端口进入(4.4 节实测回显)。
Q3:根目录跑 npm run client:build 报 EBADDEVENGINES?
根 package.json 通过 devEngines 强制 pnpm,npm 一律拒绝。安装 pnpm(corepack enable && corepack prepare pnpm@latest --activate 或 npm i -g pnpm)后改用 pnpm run client:build(4.5 节实测)。
Q4:误跑 db:seed 报 user_email_unique 冲突,有影响吗?
无影响。种子插入在撞约束时中止,未写入任何数据(4.3 节实测),库里数据不受影响。需要新管理员走界面或 API。
Q5:恢复备份后登录 401?
核对三点:恢复的库与备份文件是否同一实例(user_account 里的账号属于备份时刻的状态);.env 的 SECRET_KEY 是否与备份时一致(不一致会导致旧令牌全部失效,重新登录即可;若备份中账号密码与记忆不符,见 《4ga Boards 3.3.13 配置参数详解》 Q1);三个上传目录是否也恢复到位。
Q6:官方备份脚本对源码部署能用吗?
不能直接用。boards-backup.sh 面向 Compose 部署,按容器名(<目录名>-db-1 等)执行容器内导出;源码部署按 4.6 节的 pg_dump + tar 流程操作即可,两者产物可互相印证但不可混用恢复入口。
七、参考链接
- 官方备份/恢复脚本(源码仓库根目录):https://github.com/RARgames/4gaBoards
- server 包脚本定义(本文 scripts 实查来源):https://github.com/RARgames/4gaBoards/blob/v3.3.13/server/package.json
- 迁移与种子目录:https://github.com/RARgames/4gaBoards/tree/v3.3.13/server/db
- 本专栏相关篇目:《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 配置参数详解》