mcpField
N
nocobase-app-installer

nocobase-app-installer

github.com/nocobase云与 DevOps374 次安装4 天前更新
代码仓库

关于 nocobase-app-installer

nocobase-app-installer 技能通过已构建的部署归档安装和运行 NocoBase 3,面向生产部署场景。它管理版本发布、pm2 进程以及升级和回滚流程,不负责开发应用。

主要功能

  1. 01从部署归档安装
  2. 02使用 pm2 运行应用
  3. 03检查安装状态与健康情况
  4. 04升级并在失败时回滚
  5. 05支持本地或 SSH 部署

适用场景

  1. 01在服务器部署 NocoBase 应用
  2. 02检查现有安装和运行状态
  3. 03升级生产环境并处理失败回滚

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/nocobase/skills-v3 --skill nocobase-app-installer

安装后在 Claude Code 中输入/nocobase-app-installer确认已加载。

附带文件references/remote-deployment.md

详细介绍

使用 app-installer 安装并运行 NocoBase 3

此 Skill 安装的是已经构建好的 NocoBase——机器上不会进行任何开发,只负责运行。@nocobase/app-installer 会将每个版本安装在 releases/<version>_<build time>/app 下,并通过 pm2 运行;config.yml、app.env、storage/、backups/ 和 logs/ 位于 releases 旁边,每次升级都会保留。它从 --archive 安装,该归档由应用项目构建。本 Skill 会判断何时使用它,以及如何处理它报告的情况;每个标志的参考说明请查看 --help。

运行

在 Agent 工作所在的机器上运行安装程序,并指定 registry 和 --json。对于 SSH 部署,这里指本地机器,而不是服务器:

npx --yes --registry="${NOCOBASE_REGISTRY:-https://registry.npmjs.org}" @nocobase/app-installer@beta <command> … --json

发布的安装程序使用 @beta;不要退回到不带标签的调用或 @latest。如果现有安装需要明确版本,或用户指定了明确版本,请保留该版本;测试未发布的本地 registry 时,使用 snapshot 标签。

NocoBase 3 会发布到公共 npm registry。只有当有人将 shell 指向其他 registry(例如未发布的 snapshot)时,才会设置 NOCOBASE_REGISTRY;安装程序会将 registry 记录在 installer.json 中,并从该 registry 提供命令建议。软件包前面的 --yes 是 npx 自身的参数:它会在不询问的情况下下载安装程序。命令后面的安装程序 --yes 是另一个独立的确认选项,只能由用户提供。

除非用户指定了确切版本,否则使用已发布的 beta 渠道。未发布的 snapshot registry 会将其软件包标记为 latest;仅在测试此类 registry 时使用该标签。部署前请查看 --help,确认所选版本支持 deploy 和 --ssh。

--json 会在 stdout 上打印一个文档,并在 stderr 上输出进度,其封装格式与 pnpm nocobase … --json 相同。请读取文档,而不能只看退出代码:ok、status(success、success-noop 或 failure)、result;失败时还包括 error.code、error.message、error.suggestions 和 error.details。每条建议都包含 message;如果有可运行命令,还会包含 run,格式为 { command, args }:一个可执行文件及其参数,应原样运行,不经过 shell。app-installer 0.1.0-beta.1 及更早版本(固定到该版本的建议命令仍会运行这些版本)会将 status 输出为 error,并将 run 输出为一行 shell 命令;该命令应按输出内容原样运行,因此请通过 ok 判断成功或失败。

退出代码含义
0已完成,或无事可做(success-noop)。
1失败;未触及已经在运行的应用。
2用法无效、预检查失败,或仍需确认;未写入任何内容。
3切换后升级失败并已回滚;先前版本正在运行。
4回滚也失败;应用已停止运行。

选择部署路径

项目是由 nocobase-create-app 创建并在本地开发的源代码,用户会对其进行修改;安装则是由此 Skill 构建、仅用于运行的 NocoBase,通常用于生产环境。开始安装前,先确定部署路径:

用户要求部署路径
安装、创建或试用 NocoBase,以便进行开发nocobase-create-app Skill
将应用部署到生产环境或服务器此 Skill,使用 --archive 和应用的部署归档
使用 Docker 运行应用的 nocobase-deployment Skill 和 Docker 配置
  • 如果用户只说“在此服务器上安装 NocoBase”,但没有项目或归档,则尚未确定部署路径。要运行用户自己的应用,应先使用 nocobase-create-app 在本地创建应用、构建其归档,再使用 --archive 将其安装到此处。不要在服务器上创建项目并用 pnpm dev 运行:那是开发模式,不是部署。
  • installer.json 中的 source.kind 为 template,表示该安装由较早版本的 app-installer 从已发布的 Hub 模板安装。当前版本会以 STATE_UNSUPPORTED 拒绝处理;请交由安装该模板的 app-installer 版本处理。
  • 如果当前工作目录中已有 installer.json,则表示安装已存在:从 status 开始。

选择安装程序的运行位置

当用户提供 SSH 服务器时,请将 Agent、此 Skill 和安装程序保留在本地计算机上。继续操作前,请阅读远程部署:其中介绍了本地编排、离线执行和恢复。服务器不需要 Agent、Skill 或 npm 访问权限。以下关于 install、status、upgrade 和 rollback 的说明仍定义了生命周期;执行远程操作时,请使用相同的 SSH 选项和绝对路径的远程 --dir。

当 Agent 已在应用服务器上时,请使用以下本地命令。归档应在源代码所在的位置构建,而不是在生产环境的安装目录中构建。如果源项目在本地可用,请遵循其 AGENTS.md 和 nocobase-deployment Skill 进行构建;否则,请向用户或 CI 获取归档。不要在生产服务器上构建或运行开发项目。

构建归档

在应用项目中构建;构建方式以项目自身的 AGENTS.md 和 nocobase-deployment Skill 为准:

APP_BASE_PATH=/crm pnpm build --target linux-x64 --node-version 24 --tar
  • --target 和 --node-version 描述的是运行应用的机器,而不是构建机器:在运行应用的机器上执行 node -p "process.platform + '-' + process.arch" 和 node --version 获取对应值;Alpine 使用带 -musl 的 target。安装程序会拒绝为其他机器构建的归档,并指出适用的命令。
  • APP_BASE_PATH 会编译进客户端,未设置时为 /main。应用会在此路径下提供服务,之后构建的每个归档都必须使用相同路径。
  • SQLite 以外的数据库需要在构建前将驱动添加到项目中,例如 pnpm add @nocobase/db-postgres@beta:归档只包含构建时使用的驱动。

归档路径为 storage/exports/dist.tar.gz;用户需将其复制到运行 NocoBase 的机器上,例如 scp storage/exports/dist.tar.gz user@server:/tmp/crm.tar.gz。ARCHIVE_TOO_OLD 或 STORAGE_IN_RELEASE 表示项目中的 NocoBase 软件包版本低于安装程序所需版本:请升级这些软件包,重新构建,然后重试。

安装

所有安装方式
  1. 检查机器:运行 node --version(24 或更高版本)和 command -v pm2,后者可以在不启动守护进程的情况下查找 pm2。必须全局安装 pm2 4.3 或更高版本:npm install -g pm2;通过 npx 获取的副本会导致 pm2 startup 无法正常工作。指出缺少的内容及其安装命令,除非用户要求,否则不要全局安装任何内容。在 Windows 上,请使用 WSL。
  2. 与用户确认:目标目录(必须是新目录或空目录,例如 /srv/nocobase/crm);不含基本路径的公共源站,例如 https://apps.example.com,如果机器只能通过 http://127.0.0.1:<port> 访问,则可不提供;前面是否有反向代理;端口(默认为 13000,且机器上的每个安装都必须使用不同端口);以及数据库(默认为 SQLite)。
  3. 服务监听 127.0.0.1,适合由同一台机器上的反向代理访问;如果用户要通过 http://<address>:<port> 直接访问,则添加 --host 0.0.0.0,并将该地址用作源站。要使用其他数据库,请添加 --dialect <dialect>,通过 --set database.connections.main.host=… 等参数提供连接信息,并在用户导出密码后,使用 --set-from-env database.connections.main.password=<VARIABLE> 提供密码;绝不要将密码放在命令行中。
  4. PORT_IN_USE 会在 error.details.freePort 中给出一个可用端口;请向用户提供该端口,而不是默默地自行选择。
运行

install <dir> --archive <file> --origin <origin> --json。无需 pnpm,整个过程只需一两分钟。如果归档文件未包含 --dialect 所需的驱动程序,安装将以 DRIVER_MISSING 错误停止,并给出用于修复问题的构建命令。

成功时

当 result.started 为 true 时,表示安装已通过健康检查。请告知用户:

  • result.url,以及首次登录信息:result.initialAdmin.username 或其 email,密码位于 config.yml 中的 users.initialAdmin 下。如果 result.initialAdmin.defaultPassword 为 true,则密码仍是 config.example.yml 中的 admin123,用户必须在登录后更改;否则,密码就是用户设置的密码。结果中绝不包含密码,且不会读取 config.yml;
  • result.nextCommands 中的每条命令:pm2 startup 会输出一条命令,用户只需通过 sudo 运行一次,之后 pm2 会恢复安装程序保存的进程列表,因此重启后安装也会恢复运行;
  • 如果使用了反向代理:代理应将请求转发到安装所用的端口,并设置 WebSocket 升级标头。多个安装共用一个源站时,将根据各自的基本路径进行路由;
  • warnings 中的所有内容。

切换前安装失败时,目标目录会保持原样。失败步骤的相关信息位于 error.details 中:解压发行版时查看 output;发行版自带的 CLI 未打印结果时查看 stderr 和 stdout。如果是该 CLI 自行报告的失败,则保留 CLI 自身的错误代码(例如 CONFIG_INVALID),并通过 error.message 和 error.suggestions 说明问题所在。START_FAILED 表示已完成安装,但未运行:请显示 error.details.log。

在一台机器上安装多个实例

每个应用只安装一次,且各自使用独立目录和 --port。pm2 进程名称默认为 nocobase-<directory name>,因此目录名称不同就不会冲突;如果两个目录名称相同,则会在写入任何内容前报告 PM2_NAME_IN_USE,此时可通过 --name 为第二个实例指定不同名称。

状态

status --dir <root> --json 不会更改任何内容。请报告应用及其 version、current(发行版 ID)、endpoints.url、health.ok、process,以及 warnings 中的所有内容。node.matches: false 表示自构建发行版以来,机器上的 Node 主版本发生了变化;在为这台机器构建的发行版替换它之前,该发行版将无法加载其原生模块:警告会列出所需步骤——重新构建归档文件,然后运行 upgrade --archive;这些步骤与任何升级一样,都会经过停止、备份和确认流程。pending 非空表示某个操作已中断;请参阅下文。

升级和回滚

升级现有数据库前,请阅读目标应用及已注册插件针对该版本的升级说明。在恢复计划中纳入文档中提及的校验和变更、数据前置条件和不可逆迁移。安装程序停止应用前,请使用目标应用支持的 CLI 和部署配置检查 db repair --dry-run --json 输出,即使没有记录过往修正也应如此。这是一项只读校验和检查:安装程序自身的 db apply --dry-run 会发现待处理任务,但不会验证校验和,即使采用严格校验和策略也是如此。如果所选安装程序无法执行所需检查或准备工作,请先确定受支持的维护流程,再继续升级。

如果校验和预览建议进行变更,请在实际修复前说明每项迁移或种子校验和差异;如果没有建议变更,则跳过修复。安装程序会应用迁移,但不会自动确认已变更的历史校验和。修复只会更新历史记录中的校验和;不会更改架构、修复不完整的表,也不能替代向前迁移。不要通过更改迁移策略或反复重试同一归档来掩盖漂移。

普通安装程序升级前不要执行实际修复。SQLite 备份是在停止应用后创建的,其中已经包含新校验和;如果升级回滚,旧运行时在 onChecksumMismatch: error 下可能无法接受这些校验和。修复流程必须先停止写入、备份原始历史记录,再执行经过审核的修复和迁移;如果失败,重启旧运行时前必须恢复同一份修复前备份。额外手动备份本身并不会改变自动回滚所恢复的备份。如果所选安装程序无法协调这一流程,只完成只读检查,并先确定受支持的维护流程。

两种操作都会停止应用,因此由用户决定:

  1. 升级会获取新归档:upgrade --dir <root> --archive <file> --json。它必须是针对相同基本路径构建的同一应用,且不能是较旧版本;重新构建的相同版本也属于新发布版本,会正常部署。
  2. 不要使用 --yes 运行。它会返回 CONFIRMATION_REQUIRED,并附带 error.details.notes:将停止哪些内容、会备份哪些内容,以及 Node 主版本是否变更。将这些说明转告用户,并等用户明确同意后,再使用 --yes 重新运行。success-noop 表示该发布版本已在运行。
  3. 安装程序会备份 config.yml 中声明的所有 SQLite 数据库,以及 config.yml 和 app.env,但不会备份其他数据库:BACKUP_REQUIRED 会列出这些连接;请让用户先备份,然后添加 --backup-done。
  4. 升级会保留三个发布版本,始终包括新版本和升级前的版本;成功后会清理更旧的版本。如果用户希望保留更多版本以便回滚,请传入 --keep <n>。
  5. 查看结果:
    • 退出码为 0:新版本已通过运行状况检查。报告 result.fromVersion、result.toVersion、发布 ID result.to、result.migrations 和 result.backup,并指出 result.pruned 中的任何发布版本,因为这些版本已无法回滚到。
    • 退出码为 3:已重新运行先前的版本。报告 error.message、error.details.log,并说明数据库是否已恢复;外部数据库可能仍包含失败升级造成的变更。确认原因后,将下一次尝试留给用户决定。
    • 退出码为 4:应用已停止运行。与用户逐步处理 error.suggestions。 rollback --dir <root> --json 会返回到上次升级前的版本,或返回到 --to <release id or version> 指定的版本。如果该次升级迁移了 SQLite 数据库,且安装程序保留了数据库备份,回滚时会恢复备份,并丢失此后存储的所有内容;确认提示会说明这一点,并且同样需要转发确认步骤。外部数据库需要单独执行恢复流程:--backup-done 不会让安装程序恢复这些数据库。如果不可逆迁移导致架构与先前的运行时不兼容,要返回该运行时,也必须有兼容的数据库备份。--no-restore 会保留当前数据库;只有在确认数据库与所选运行时兼容时才使用此选项。

恢复中断的操作

upgrade 返回 OPERATION_INTERRUPTED,或 status 中显示 pending,表示先前的运行在应用停止期间中断。直接运行 rollback 即可通过相同的确认步骤恢复:撤销中断的升级并恢复数据库,或完成中断的回滚。

更改源地址或端口

app-installer 没有用于此操作的命令。源地址、主机地址和端口在 app.env 中,分别对应 APP_PUBLIC_ORIGIN、APP_SERVER_HOST 和 APP_SERVER_PORT。更改前,请告知用户:

  • 应用的新访问地址将由新源地址和基础路径组成;
  • 应用重启时会短暂停止运行;
  • 新端口必须未被占用,否则应用重启后会陷入崩溃循环,且只有 logs/app.err.log 能说明原因;此外,前置反向代理必须将请求转发到该端口;
  • 无法通过这种方式更改 APP_BASE_PATH:它已编译到客户端中。

在用户同意后,只编辑这三行,不要更改其他内容,然后运行 pm2 restart <name>,其中 <name> 是 status 中的 name。pm2 会通过 launcher.mjs 启动应用,该文件每次启动时都会读取 app.env,因此无需重新注册任何内容。之后,status 会报告新的 endpoints,并检查 app.env 中地址的运行状况;如果源地址变了,请让用户打开 endpoints.url。

保持数据完整

根目录中存放着应用配置、密钥和数据的唯一副本。除上述 app.env 中的三行外,所有更改都通过 app-installer 进行;是否删除任何内容,应由用户决定。不要在对话中透露 config.yml 的内容,该文件包含密钥。

评论

支持 Markdown