Huly 常用 CLI 命令与运维实战

Huly selfhost 运维命令矩阵(v0.7.426 实测):run-tool.sh 封装机制与管理工具 40+ 命令清单、账号/工作区/令牌/备份/索引核心命令逐个实测回显、Compose 运维矩阵与重启顺序纪律、备份产物结构与升级迁移路径,含运维视角排障沉淀(2026-10-27)。

HulyHuly项目管理2026/10/27

Huly 常用 CLI 命令与运维实战

目标:梳理 Huly selfhost 实例的日常运维入口与命令矩阵——官方管理工具(run-tool.sh 封装的 hardcoreeng/tool)的完整命令清单与核心命令实测、Compose 编排运维矩阵、备份恢复体系、账户与工作区管理路径、全文索引重建,以及运维视角的排障沉淀。部署与配置细节分别见《Huly 0.7.426 Docker Compose 部署实战》与《Huly 配置参数详解》。本文全部命令在 v0.7.426 实例实测(2026-10-27)。

一、环境信息与运维入口总览

项目值
Huly 版本v0.7.426
运维对象官方 selfhost 编排(14 个服务,Compose 项目 huly-0.7.426-stack)
管理工具hardcoreeng/tool:v0.7.426(由仓库 run-tool.sh 封装)
实测日期2026-10-27

Huly 没有传统意义的裸机命令行程序——平台本体以一组服务进程交付,运维入口共三个:

入口载体适用场景
管理工具仓库根目录 ./run-tool.sh <命令>账号/工作区/令牌/备份/索引等数据面管理
Compose 命令docker compose <子命令>服务启停、日志、状态、重建
Web 控制台浏览器(管理员/工作区设置)成员邀请、权限、工作区级备份(Settings → Backup)

1.1 管理工具封装机制(run-tool.sh)

run-tool.sh 是理解 Huly 运维的关键脚本:它读取 huly_v7.conf,把 SECRET、CR_DB_URL、STORAGE_CONFIG(minio|minio?accessKey=minioadmin&secretKey=minioadmin)、ACCOUNTS_URL、TRANSACTOR_URL、QUEUE_CONFIG 等连接参数注入一个同版本 hardcoreeng/tool 临时工作负载,连入编排网络后执行 bundle.js 对应子命令。这解释了两个行为:

  1. 管理工具命令必须整栈在跑才能执行(它直连 account/transactor/队列/对象存储);
  2. 需要额外参数(挂载备份目录、补环境变量)时通过 RUN_TOOL_DOCKER_ARGS 透传,如 RUN_TOOL_DOCKER_ARGS="-v /abs/backup:/backup"。

不带参数运行进入交互式 shell(内部排查利器);带参数则以命令方式执行,如 ./run-tool.sh create-account user@example.com -p pass -f First -l Last。

二、管理工具命令清单(--help 实测)

$ ./run-tool.sh --help
Usage: bundle [options] [command]

Options:
  -V, --version     output the version number
  -h, --help        display help for command

Commands:
  version
  create-account [options] <email>                create user and corresponding account in master database
  assign-workspace <email> <workspace>            assign workspace
  create-workspace [options] <name> <owner_social_id>   create workspace
  set-user-role <email> <workspace> <role>        set user role
  upgrade-workspace [options] <name>              upgrade workspace
  backup [options] <dirName> <workspace>          dump workspace transactions, blobs and accounts
  backup-find [options] <dirName> <fileId>        dump workspace transactions and minio resources
  backup-compact [options] <dirName>              Compact a given backup, will create one snapshot clean unused resources
  backup-check <dirName>                          Compact a given backup, will create one snapshot clean unused resources
  backup-check-all [options]                      Check Backup integrity
  backup-restore [options] <dirName> <workspace> [date]   dump workspace transactions and minio resources
  backup-s3-compact [options] <bucketName> <dirName>      Compact a given backup to just one snapshot
  backup-s3-download [options] <bucketName> <dirName> <storeIn>  Download a full backup from s3 to local dir
  generate-token [options] <name> <workspace>     generate token
  profile [options] <endpoint> <mode>             Enable or disable profiling
  generate-persons [options] <workspace>          generate a random persons into workspace
  decode-token <token>                            decode token
  configure [options] <workspace>                 clean archived spaces
  change-field [options] <workspace>              change field value for the object
  fulltext-reindex <workspace>                    reindex workspace
  fulltext-reindex-all                            reindex workspaces
  move-account-db-to-pg
  migrate-created-modified-by [options]
  ensure-global-persons-for-local-accounts
  migrate-merged-accounts
  filter-merged-accounts-in-members
  migrate-github-account [options]
  queue-init-topics [options]                     create required kafka topics
  migrate-gmail-account [options]
  migrate-calendar-integrations-data [options]
  restore-markup-refs [options]
  restore-github-integrations [options]
  migrate-trusted-v6-accounts [options]           Migrate trusted v6 accounts
  restore-from-v6-all <dirName>                   Restore from full v6 dump
  restore-v6-from-storage [options] <workspace> <accsRoot>  Restore a workspace from v6 backup storage with accounts info
  migrate-chat-to-communication [options]         Migrate old chat to new communication
  calculate-ratings [options] <workspace>         Perform a rating re-calculation
  ensure-missing-social-identities [options] <workspace>
  help [command]                                  display help for command

命令分五类:账号与工作区(create-account/assign-workspace/create-workspace/set-user-role)、令牌(generate-token/decode-token)、备份恢复(backup 全家族)、索引与队列(fulltext-reindex/queue-init-topics)、版本迁移(migrate-/restore--v6/upgrade-workspace,配合仓库 MIGRATION.md 使用)。日常运维高频命令逐个实测如下。

三、核心命令实测

3.1 version 与工具版本

$ ./run-tool.sh version
tools git_version:  model_version:  {"major":0,"minor":6,"patch":0}

model_version 显示工具内置的数据模型版本(0.6.0),执行数据迁移类命令前可据此与平台版本对照。

3.2 账号管理:create-account / assign-workspace / set-user-role

创建账号(-p 密码、-f/-l 姓与名,实测密码策略接受 8 位字母数字):

$ ./run-tool.sh create-account root@huly.local -p q1w2e3r4 -f Root -l Admin
creating account Root Admin (root@huly.local)...

重复创建同邮箱账号的显式报错(实测回显,不覆盖已有账号):

$ ./run-tool.sh create-account admin@huly.local -p q1w2e3r4 -f Admin -l User
creating account Admin User (admin@huly.local)...
An account with the provided email already exists email="admin@huly.local"
PlatformError: ERROR: platform:status:AccountAlreadyExists {}
    at signUpByEmail (/usr/src/app/bundle.js:249705:17)
    ...

把用户指派进已有工作区:

$ ./run-tool.sh assign-workspace root@huly.local demo
assigning user root@huly.local to demo...

工作区内角色调整用 set-user-role <email> <workspace> <role>(如把成员提为 workspace 级管理员)。数据库侧核对路径:主库 global_account schema 的 person/social_id/account_passwords 表(查询示例见《Huly 配置参数详解》4.2 节)。

3.3 工作区管理:create-workspace

$ ./run-tool.sh create-workspace demo "email:root@huly.local"
...(模型初始化过程日志,结束后工作区可登录)

第二个参数是所有者 social id(email:<邮箱> 格式)。支持选项:-i/--init 从既有工作区初始化、-r/--region、-d/--dataId、-b/--branding(多品牌部署)。建完核对(主库 workspace 表,实测回显):

name      data_id  created_by
demo      NULL     5ea0f331-f8bc-49ba-8b0c-28668f021b02
devteam   NULL     398d66a5-24d2-4146-901c-3c80e80964db

3.4 令牌管理:generate-token / decode-token

为指定用户+工作区签发服务令牌(用于脚本调用平台接口):

$ ./run-tool.sh generate-token root@huly.local demo
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHRyYSI6eyJzZXJ2aWNlIjoidG9vbCJ9...(JWT,实测输出)

解码验看载荷(实测回显):

$ ./run-tool.sh decode-token <上面输出的令牌>
{
  extra: { service: 'tool' },
  account: '398d66a5-24d2-4146-901c-3c80e80964db',
  workspace: 'dc150071-f9ee-4af5-b0de-861bc2d73f3b'
}

载荷三要素:签发来源服务(extra.service)、账号 UUID、工作区 UUID。令牌由顶层 SECRET 签名——更换 SECRET 后所有旧令牌失效(配置篇 2.7 节)。

3.5 备份:backup 与产物结构

工作区级导出(挂载宿主机备份目录):

$ mkdir -p /opt/data/quzuo/tmp/huly/backup
$ RUN_TOOL_DOCKER_ARGS="-v /opt/data/quzuo/tmp/huly/backup:/backup" ./run-tool.sh backup /backup/devteam-bak devteam
<<<< chunk domain="documents" needRetrieve=0 toLoad=36 workspace="dc150071-..." url="devteam" lastSize=0
>>>> upload pack domain="documents" storageFile="000001/documents-data-1793105683976-0001.tar.gz" size=1935 ...
processed domain="questions" processed=0 digest=0 time=1 ...
...
end backup workspace="dc150071-f9ee-4af5-b0de-861bc2d73f3b" totalTime=649

产物结构(实测清点,整包 116 KB):备份目录下按快照批次建子目录(000001/),每个数据域一对文件——<域>-<时间戳>-0001.snp.gz(快照元数据)+ <域>-data-<时间戳>-0001.tar.gz(数据包)。实测出现的域:tx、model_tx、_migrations、space、activity、tags、documents、sequence、hr、love——与该工作区实际产生的数据域一致,空域不落文件。

备份家族的分工:

命令用途
backup <dir> <ws>导出工作区全量(事务+附件+账号)
backup-restore <dir> <ws> [date]按日期点恢复到指定工作区
backup-check / backup-check-all校验备份完整性
backup-compact <dir>合并快照并清理无用资源
backup-s3-download / backup-s3-compact对象存储侧整桶备份下载与合并

另两条备份路径:Web 控制台 Settings → Backup(工作区管理员自助导出,官方 backup-restore.md 指南描述的跨实例迁移主路径);对象存储与数据库卷的文件级备份(见第四节运维矩阵)。

3.6 全文索引重建:fulltext-reindex

$ RUN_TOOL_DOCKER_ARGS="-e FULLTEXT_URL=http://fulltext:4700" ./run-tool.sh fulltext-reindex demo
done demo

命令经队列通知 fulltext 服务重建指定工作区索引。验证(搜索引擎侧索引计数,实测):

index                  docs.count store.size
huly_storage_index_v2         96    102.6kb

适用场景:Elasticsearch 数据卷重置、索引与服务数据出现偏差、或队列积压丢失后补齐。全实例重建用 fulltext-reindex-all。注意:漏传 FULLTEXT_URL 会报 please provide FULLTEXT_URL(用 RUN_TOOL_DOCKER_ARGS 注入)。

四、Compose 运维矩阵

4.1 状态与日志

docker compose ps                          # 14 服务状态一览(healthy/unhealthy)
docker compose logs -f account             # 跟踪账号服务日志(注册/登录问题首查点)
docker compose logs --tail 50 fulltext     # 最近 50 行(队列消费问题首查点)

排障时的服务定位经验:接入问题看 nginx → 登录注册看 account → 数据读写看 transactor → 搜索看 fulltext/elastic → 事件流转看 redpanda 下游消费方。

4.2 启停与重建

docker compose up -d                # 全栈拉起(含配置变更后的滚动重建)
docker compose restart fulltext     # 重启单个服务(依赖恢复后的收敛动作)
docker compose down                 # 停栈保留数据卷
docker compose down -v              # 停栈并删除命名卷(bind mount 目录需手动清理)

重启顺序纪律(实测教训,详见部署篇排障实录):强依赖队列/数据库的下游服务(fulltext 等)在依赖方重启后必须自身重启,否则进程内 DNS/连接缓存导致持续消费失败;改完配置统一 up -d 滚动重建可避免该类半恢复状态。

4.3 数据层健康核对

数据库与搜索引擎的健康检查命令(内网直连,实测均可用):

# 主库:库清单与工作区清单(凭据取 huly_v7.conf 的 CR_USER_PASSWORD)
echo "SHOW DATABASES;" | ./cockroach sql --url "postgres://selfhost@localhost:26257/defaultdb?sslmode=disable"

# 搜索:索引文档数
curl -s 'http://<elastic>:9200/_cat/indices/huly_storage_index_v2?v&h=index,docs.count,store.size'

五、升级与迁移操作路径

版本升级的完整动作链(官方 README + MIGRATION.md 流程):先读 MIGRATION.md 确认目标版本段(如 v0.7.426 段若写「No changes required」即可直接升级)→ docker compose down → 更新仓库 → 改 huly_v7.conf 的 HULY_VERSION/DESKTOP_CHANNEL → docker compose pull → docker compose up -d。跨大版本(0.6.x → 0.7.x)必须按 MIGRATION.md 的 v0.7 专节分步迁移(尤其 v0.7.204 节点),此时管理工具的 migrate-*/upgrade-workspace/restore-from-v6-all 命令族就是迁移动作的执行载体。

升级前基线动作:对全部工作区执行 backup(3.5 节)或 Web 端 Settings → Backup 导出,留好回退路径。

六、运维排障沉淀

6.1 管理工具连不上服务

run-tool.sh 执行报网络不存在时(Network ... not found. Start the stack first),说明编排未启动——工具与业务服务同网络直连,先 docker compose up -d。若栈在跑但工具报连接超时,核对 run-tool.sh 推断的网络名(匹配 _huly_net 后缀)与实际编排网络是否一致(改过 DOCKER_NAME 时重跑 setup.sh 同步)。

6.2 队列消费方失联(EAI_AGAIN)

消息队列重启后,fulltext 日志持续 Connection error: getaddrinfo EAI_AGAIN redpanda 且索引停止更新——进程内 DNS 收敛失败无法自愈,docker compose restart fulltext 后消费组重新入组(实测日志:[ConsumerGroup] Consumer has joined the group),随后 fulltext-reindex 补齐索引(0 → 96 条文档)。完整根因链见部署篇排障实录四。

6.3 队列健康探针 unhealthy 的判读

编排内队列服务长期显示 unhealthy 但业务正常:探针带 SASL 凭据连接未启用认证的队列实例(--mode dev-container),返回 ILLEGAL_SASL_STATE。以业务信号判读队列健康:transactor/account 日志无队列连接错误、fulltext 消费组在组、事件正常流转,即健康。

6.4 数据目录权限(运维巡检项)

自定义数据卷路径的部署,把「属主巡检」纳入运维例行:数据目录属主须匹配服务内运行用户(多数服务 uid 1000、队列服务 uid 101),属主漂移会直接导致服务起不来(Permission denied/AccessDeniedException)。修复:chown -R <uid>:<uid> <数据目录> 后重启对应服务。

七、本章小结

Huly 运维的命令面由「一个管理工具 + 一套编排命令」构成:管理工具覆盖数据面(账号/工作区/令牌/备份/索引/迁移),编排命令覆盖进程面(启停/日志/状态)。三条高频路径值得固化:初始化路径(create-account → create-workspace → assign-workspace)、备份路径(backup 定期导出 + 卷级快照双保险)、索引路径(fulltext-reindex 收敛搜索引擎偏差)。掌握 3.5 节备份产物结构与 4.2 节重启纪律,即可把大部分事故控制在可恢复范围内。