百积木文档
开发指南后端应用开发

完整构建与部署链路

从项目主线发布不可变语义版本,完成 Environment 绑定、版本部署与验证。

具体参数以本机 CLI 和当前平台版本为准。开始前先发现可用命令:

baijimu --version
baijimu hosted-service --help
baijimu hosted-service project --help

版本使用严格 SemVer,并与 Cargo.tomlpackage.version 完全一致。首次请求固定源码;失败、取消或请求中断后的重试沿用原版本来源,主线变化不会换源。修改源码必须发布新版本。SHA 只用于内部来源追溯,不再作为构建输入。

标准生命周期

后端 Project 与指定 Cargo package.version
  -> Release Operation
  -> 不可变 hosted_service_release Artifact
  -> Project Environment
  -> Slot 计算资源
  -> Database/Object Storage Provider Binding 与 Secret
  -> Deployment
  -> 稳定 Endpoint
  -> 健康、鉴权与真实业务验证

Project 是后端应用身份,Environment 保存环境配置和资源引用,Slot 提供运行计算,Provider Binding 选择已经 创建的基础资源,Deployment 把已发布项目版本运行在目标 Environment。Hosted Service 是这条托管能力,不是 还要额外创建的业务资源。

准备项目

构建前确认:

  • 项目属于目标工作区。
  • 待发布源码已经合并到平台 Project 的主线 HEAD。
  • Cargo.tomlpackage.version 是本次要发布的规范 SemVer 2.0.0。
  • 项目在平台构建环境中能够完成依赖安装、测试和构建。
  • 密钥和环境配置没有写入源码。
  • 每个声明的 HTTP Endpoint listener 都实现固定的 GET /healthz,并在可接收业务流量时返回 2xx。
  • 已通过 Rust 服务设计约束 中的类型所有权、 JSON 边界、显式转换、契约测试和 CI 检查。

项目版本 Artifact 契约

项目版本发布生成的 Artifact 类型固定为 hosted_service_release。项目根目录必须提供 hosted-service.toml;发布器首次从平台主线校验并固定源码,把二进制、hosted-service.manifest.json、 版本身份和同源迁移声明封装成一个不可变项目版本。

历史 rust_binaryrust_bundlehosted_service_bundle 都不是项目版本发布制品,不能传给 deploy-version。不要恢复按 artifactId 部署的旧入口,也不要通过开放旧类型、复制 Secret 到 Artifact 或绕过部署校验来恢复服务。

创建 hosted-service.toml

Manifest 属于项目源码,必须放在项目根目录并随待构建 commit 一起提交。可以直接让 CLI 生成一个经过 平台同源契约校验的模板:

baijimu hosted-service manifest init \
  --entrypoint target/release/example-service
baijimu hosted-service manifest validate hosted-service.toml

默认不会覆盖已有文件;确认覆盖时显式增加 --force。需要让 AI、编辑器或代码生成器发现完整结构时, 使用以下命令取得机器可读 JSON Schema:

baijimu hosted-service manifest schema

不依赖 CLI 时,可以从下面的最小模板开始:

contract_version = "3.0.0"

[service]
entrypoint = "target/release/example-service"

[[service.endpoints]]
name = "http"
protocol = "http"
auth_mode = "token"
primary = true
required = true

字段和约束如下;未知字段会被拒绝:

字段是否必填约束
contract_version当前必须精确为 3.0.0,使用严格 SemVer 字符串。
service.entrypoint项目内非空相对路径;不能是绝对路径,不能包含 ... 路径段。若构建命令同时传 --binary-path,两者必须相同。
service.endpoints1–32 个 Endpoint,名称不能重复。
name1–63 个字符;小写字母开头,只能包含小写字母、数字和连字符,并以小写字母或数字结尾。
protocol当前只支持 http
auth_mode只能是 nonetoken
primary默认 false;整个 Manifest 必须且只能有一个 primary = true
required默认 true;primary Endpoint 必须是 required。

none 表示 Runtime 不校验 Hosted Service consumer token;token 表示只接受绑定到当前 Endpoint 的 consumer token。Hosted Service 不解释 Endpoint 名称、调用方或业务用途,token 不承载租户、管理或其他 业务语义。业务应用需要的租户鉴权必须由应用自己的协议和数据源实现。不要在 Manifest 中写端口、域名、 base_url、Secret 或环境差异配置。Runtime 会在每次部署时分配监听端口,并按 Endpoint 名称注入 APP_ENDPOINT_<NORMALIZED_NAME>_PORT;后端在 127.0.0.1 上使用对应变量绑定 listener。完整运行时字段和变量转换规则见 配置、Endpoint 与服务鉴权。平台不提供 APP_PORT 兼容注入。 健康路径同样不在 Manifest 或 Environment 中声明:Hosted Service 固定请求每个 listener 的 GET /healthz, 任何健康路径覆盖字段都会被拒绝。

一个进程可以声明多个 Endpoint,例如在上述 primary http Endpoint 后追加管理入口:

[[service.endpoints]]
name = "management"
protocol = "http"
auth_mode = "token"
primary = false
required = true

发布并等待项目版本

baijimu hosted-service project release <projectId> \
  --workspace-id <workspaceId> \
  --version <projectVersion> \
  --json

命令不接收任意 commit、版本或 Artifact ID。平台读取当前主线 HEAD 和根 Cargo.tomlpackage.version,并返回 releaseOperationId。使用该 ID 查询状态:

baijimu hosted-service project release-status <releaseOperationId> \
  --workspace-id <workspaceId> \
  --json

只有 Release Operation 进入 SUCCEEDED,对应 hosted_service_release 已登记后,该 projectVersion 才能部署。相同 Project 与版本只能绑定一个主线 commit;源码变化后再次发布必须先按 SemVer 提升 package.version 并重新合并主线。

Artifact 元数据由独立 Artifact Service 持有。需要恢复或核对项目制品时使用 CLI 查询:

baijimu rust-build artifact list <workspaceId> --project-id <projectId>

Artifact 查询仅用于审计和故障定位;正常部署以 projectId + projectVersion 解析不可变制品,不接受 artifactIdrust-build artifact 是 CLI 的查询分组,不改变 Artifact Service 的所有权。

为项目创建环境

baijimu hosted-service env create <workspaceId> \
  --project-id <projectId> \
  --name <environmentName>

Project 是唯一部署身份,不再额外创建 Hosted Service 资源。外部仓库也必须先登记为平台 Project, 再使用真实 projectId 创建 Environment;不要把展示名或列表第一项当作资源 ID。

准备并分配 Slot

Environment 本身不提供计算资源。部署前先读取工作区已有 Slot 和当前可用目录:

baijimu hosted-service slot list <workspaceId> --json
baijimu hosted-service slot types <workspaceId> --json

工作区尚未领取基础 Slot 时,可以幂等创建或返回该基础 Slot:

baijimu hosted-service slot create \
  --workspace-id <workspaceId> \
  --json

需要购买付费 Slot 时,必须使用 slot types 返回的当前已发布 Offer,不得在脚本或文档中固定 SKU、价格或 Offer ID。取得真实 slotId 后分配给 Environment:

baijimu hosted-service slot assign \
  --workspace-id <workspaceId> \
  --environment-id <environmentId> \
  --slot-id <slotId>

Slot 可以承载多个相互隔离的 Environment,但它不包含数据库或对象存储。资源关系、计费和停止/退役边界见 Project、Environment、Slot、Endpoint 与数据库

创建并绑定基础资源(按需)

数据库和对象存储必须先通过各自的工作区资源入口创建,Environment 再保存对应 Profile 的稳定引用。 Resource Binding 不负责购买或创建资源,也不会把资源所有权转移给 Project。

  1. 从当前 Runtime 或工作区资源入口确认可用能力。
  2. 按当前方法定义申请 Database Profile 或 Object Storage Profile。
  3. 安全保存首次返回的 Profile Token;不要写入项目 Git、Artifact、普通配置或命令历史。
  4. 从当前 Hosted Service Provider 目录确认 Environment 支持目标 Provider。
  5. 使用真实 profileRef 创建配置绑定。

先读取动态 Provider 目录和命令参数:

baijimu hosted-service config-provider --help
baijimu hosted-service config-binding --help

创建绑定时使用 Provider 返回的真实 providerKey、资源返回的真实 profileRef,不要从示例推导:

baijimu hosted-service config-binding create \
  --workspace-id <workspaceId> \
  --environment-id <environmentId> \
  --name <bindingName> \
  --provider-key <providerKey> \
  --profile-ref <profileRef>

消费者支持范围以当前 Hosted Service Provider 目录为准。看到某项 Runtime 基础能力,不代表 Hosted Service 一定支持把它绑定到 Environment。数据库、对象存储的申请与 Profile 边界见 基础能力与 Resource Binding

写入环境 Secret(按需)

第三方 API 密钥等不由 Provider 解析的敏感值,写入 Environment Secret snapshot。先读取当前键名和 Environment Revision,再通过显式 patch 更新;查询不会回显 Secret 明文:

baijimu hosted-service env secret-get \
  --workspace-id <workspaceId> \
  --environment-id <environmentId>

baijimu hosted-service env secret-update \
  --workspace-id <workspaceId> \
  --environment-id <environmentId> \
  --expected-version <environmentRevision> \
  --upserts-json-file ./secrets.json \
  --change-reason "configure production service"

Secret 文件必须放在权限受控的临时位置且不进入 Git。普通非敏感配置、Provider 投影字段、Secret 更新和冲突 处理见环境配置与服务鉴权

部署项目版本

baijimu hosted-service project deploy-version <projectId> \
  --workspace-id <workspaceId> \
  --environment-id <environmentId> \
  --version <projectVersion> \
  --json

部署请求返回后继续查询部署记录:

baijimu hosted-service project deployments <projectId> \
  --workspace-id <workspaceId> \
  --environment-id <environmentId>

只有 deployment 进入成功运行状态、Endpoint 健康且真实业务请求通过,发布才算完成。

部署完成后应保存并核对这组可追踪身份:

sourceCommitId
  -> releaseOperationId
  -> projectVersion
  -> artifactId
  -> environmentId
  -> deploymentId
  -> Endpoint baseUrl

先检查每个声明 Endpoint 的固定 GET /healthz,再按其 authMode 使用真实 consumer token 或业务认证完成请求。 只看到进程运行、部署请求返回成功或 Endpoint URL 已生成,都不能单独证明发布完成。完整检查项和恢复流程见 发布验证与故障排查

配置和 Secret 变更何时生效

Environment 配置和 Secret 在启动业务进程时解析。更新 Secret 只会改变环境的配置源事实,不会修改已经 运行的进程环境,也不会修改不可变 Artifact;因此现有进程不会自动读取新值。更新后必须通过平台支持的 重启操作,或者重新部署一个已经发布的项目版本,再验证新进程、健康检查和真实业务请求。

历史 deployment 可能仍引用 rust_binaryrust_bundlehosted_service_bundle。它们只用于审计,不能 作为新版本部署输入。应把对应源码纳入当前项目主线、设置新的规范 package.version,再执行项目版本发布。

需要变更数据库时,不要在服务启动脚本中执行迁移,也不要让 Bundle、Module、baijimu-agent 或 Control Plane 参与迁移。Schema 与 Data Migration 必须和运行程序一起从同一个项目版本发布,并由发布清单 声明;完整流程见 数据库迁移

发布操作不是部署版本

releaseOperationId 只能查询发布过程;部署必须使用成功发布后返回的 projectVersion

不要恢复 deploy-artifact

deploy-artifact 已退出当前 CLI 和项目版本协议。旧 hosted_service_bundle 即使 Manifest 合法,也不能代替 hosted_service_release;应先发布项目版本,再用 deploy-version 部署。

本页内容