CLI 与云 API 部署参考
在 CI/CD、脚本或自建平台中,可以不经控制台触发部署。本页列出命令、选项和接口参数。第一次部署想先跑通一遍,见 教程:部署示例项目。
| 方式 | 适用场景 | 代码来源 |
|---|---|---|
| CLI | CI/CD 流水线、本地脚本 | 本地或 CI 工作目录 |
| 云 API | 自建平台、服务端调用 | Git 仓库或代码压缩包 |
CLI 部署读取 cloudbaserc.json 中声明的资源,配置文件见 配置文件。
通过 CLI 部署
登录
非交互环境使用云 API 密钥或环境级 API Key 登录。密钥存放在 CI 的 Secrets 中,不写入仓库。
tcb login --apiKeyId <SecretId> --apiKey <SecretKey>
更多登录方式见 登录认证。
声明式部署
在项目根目录执行:
tcb deploy --dry-run # 预览变更,不实际部署
tcb deploy --yes # 部署,已存在的云函数直接覆盖
常用选项:
| 选项 | 说明 |
|---|---|
--dry-run | 输出变更计划,不实际部署 |
--yes | 已存在的云函数直接覆盖,不再确认 |
--only / --skip | 只部署或跳过指定类型的资源 |
--env-id | 指定目标环境 |
--mode | 应用 cloudbaserc.json 中对应的环境覆盖配置 |
--continue-on-error | 某个资源失败后继续部署其余资源 |
任一资源部署失败时,命令以非零退出码结束,CI 据此判断部署结果。完整选项见 声明式部署(tcb deploy)。
声明式部署覆盖云函数、云应用、静态托管、网关路由和数据库迁移,不包含云托管。已存在的资源按 cloudbaserc.json 的声明收敛:云函数覆盖更新,配置一致的网关路由跳过。
有构建步骤的静态托管,先执行 tcb app build 再执行 tcb deploy:
npm install --prefix web # 依赖安装在 hosting[].root 目录
tcb app build # 本地构建,不安装依赖
tcb deploy --yes
outputDir 已存在时,tcb deploy 直接上传其中的内容。修改源码后漏掉 tcb app build,上传的仍是上一次的产物。
部署云托管
云托管使用 tcb cloudrun deploy 单独部署,服务不存在时自动创建,已存在时更新并生成新的部署记录:
tcb cloudrun deploy -s demo-run --source ./cloudrun/demo-run --port 3000 --force --yes --wait
| 选项 | 说明 |
|---|---|
-s | 服务名称 |
--source | 代码目录,目录内需要有 Dockerfile(容器型服务) |
--port | 容器型服务的监听端口 |
--force / --yes | 跳过确认,用于非交互环境 |
--wait | 等待部署任务完成后再返回 |
完整参数见 代码部署。
部署记录和状态:
tcb cloudrun record list -s demo-run -e <envId>
新版本构建期间状态为 creating,变为 normal 且流量比例为 100 后,新版本才开始接收请求。切换完成前的短暂时间内,访问到的仍可能是旧版本。
云端构建部署
有安装依赖和构建步骤的前端项目,使用 tcb app deploy 在云端完成“安装依赖 → 构建 → 上传产物 → 绑定路由”:
cd web
tcb app deploy my-app --framework vite --force -e <envId>
结果是“应用”列表中的一个应用,有独立的访问域名和版本记录,与 hosting 部署的静态文件目录不同,见 静态网站托管的两种部署形态。
⚠️ 在应用目录内执行命令。使用
app.root或--cwd从项目根目录指向子目录时,CLI 打包的是子目录,却把子目录路径提交给云端构建,构建在安装依赖步骤失败,日志为cd: can't cd to /root/cloudbase-workspace/./web。
首次部署成功后,CLI 会在执行目录写入 cloudbaserc.json。应用目录与项目根目录不同时,注意不要留下两份配置文件。
构建失败时,CLI 只输出通用的排查提示。查看失败原因:
tcb app versions list my-app -e <envId> # 获取版本名称和构建 ID
tcb api tcb DescribeCloudBaseRunBuildLog --api-version 2018-06-08 \
--body '{"EnvId":"<envId>","ServiceName":"my-app","ServiceVersion":"my-app-001","BuildId":<BuildId>,"Start":0}'
通过云 API 部署
调用云 API CreateCloudApp,DeployType 填 custom,云端拉取代码、执行构建命令并完成部署。
| 项目 | 值 |
|---|---|
| 接口域名 | tcb.tencentcloudapi.com |
| Action | CreateCloudApp |
| Version | 2018-06-08 |
| 请求频率限制 | 20 次/秒 |
完整的接口定义见 创建云应用。公共参数、签名方式见 公共请求参数。可使用 API Explorer 在线调试并生成 SDK 代码。
调用流程
- 代码来源为压缩包时,先调用
DescribeCloudAppCosInfo获取上传地址并上传代码,见 上传代码包。代码来源为 Git 仓库时,跳过此步。 - 调用
CreateCloudApp,传入代码来源和构建命令,返回BuildId和VersionName。 - 调用
DescribeCloudAppVersion查询构建状态,直到状态为SUCCESS或FAILED。 - 调用
DescribeCloudBaseRunBuildLog查看构建日志,见 查询构建状态和日志。
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
EnvId | String | 是 | 环境 ID |
ServiceName | String | 是 | 服务名称,对应控制台的流水线名称 |
DeployType | String | 是 | 部署类型:custom 为自定义流水线,static-hosting 为静态托管应用 |
Source | Object | 是 | 代码来源,见 Source |
Commands | Object | 否 | 构建命令,见 Commands |
CustomSteps | Array | 否 | 自定义步骤,见 CustomSteps |
Env | Array | 否 | 非敏感环境变量,构建容器中以 $KEY 引用 |
Secrets | Array | 否 | 敏感凭证,见 Secrets |
NodeJsVersion | String | 否 | 构建使用的 Node.js 版本,如 16、18、20、22、24 |
WorkingDir | String | 否 | 全局工作目录,如 ./。对应控制台的“目标目录” |
PreDeployCommand | String | 否 | 部署前执行的命令 |
PostDeployCommand | String | 否 | 部署后执行的命令 |
Runner | Object | 否 | 构建容器配置,Runner.Cpus 指定 CPU 核数,如 16。对应控制台的“容器规格” |
BuildType | String | 否 | 构建类型,如 ZIP |
Commands 和 CustomSteps 至少填写一个。docker 镜像构建场景推荐使用 CustomSteps。
⚠️ 构建环境中的 CLI 已登录,但不会自动带上目标环境。部署命令里的
tcb hosting deploy等命令需要用-e <envId>指定环境,否则部署步骤报No valid environment ID was detected。tcb deploy读取项目里cloudbaserc.json的envId,不需要额外指定。
DeployType为custom时,产物部署到静态托管的文件目录,不会出现在控制台“应用”列表,见 静态网站托管的两种部署形态。
Trigger参数(Webhook 触发)暂未对外开放。传入该参数不会报错,但不生效。
Source
| 参数 | 类型 | 说明 |
|---|---|---|
Type | String | 代码来源类型:git、zip |
Repo | String | Git 仓库的 HTTPS 地址,或压缩包的完整下载地址 |
Ref | String | Git 分支、Tag 或 Commit,默认 main。zip 类型忽略此参数 |
Channel | String | Git 平台:git、github、gitlab、gitee、coding。私有仓库必填 |
IsPrivate | Boolean | 是否私有仓库。为 true 时,平台自动注入带鉴权的克隆地址 |
CodeUrlWithAuth | String | 自行传入的带鉴权克隆地址或带签名的压缩包下载地址,优先级最高 |
CosTimestamp | String | zip 类型使用,填 DescribeCloudAppCosInfo 返回的 UnixTimestamp |
CosSuffix | String | zip 类型使用,压缩包后缀,默认 .zip |
PackageFileName | String | 压缩包名称,如 package.zip |
⚠️
CodeUrlWithAuth包含访问令牌。使用权限最小、有效期短的令牌,并避免在日志中输出请求内容。
git 类型的 Repo 须满足:
- 使用
https协议 - 域名属于 GitHub、GitLab、Gitee、Bitbucket 或 Coding
- 不指向内网 IP
- 不含反引号、
$、双引号、反斜杠和换行
Commands
对应控制台“简易命令”模式,见 命令模式。
| 参数 | 类型 | 说明 |
|---|---|---|
InstallCmd | String | 安装命令,如 npm install |
BuildCmd | String | 构建命令,如 npm run build |
DeployCmd | String | 部署命令,如 tcb deploy --yes |
CustomSteps
对应控制台“自定义编排”模式。步骤按数组顺序执行。
| 参数 | 类型 | 说明 |
|---|---|---|
Name | String | 步骤名称,建议使用 kebab-case,如 build-image |
Command | String | shell 脚本,支持单行或多行 |
命令含 docker build 或 docker push 时,构建环境提供 Docker 服务。
Env
| 参数 | 类型 | 说明 |
|---|---|---|
Key | String | 变量名,以字母或下划线开头,只能包含字母、数字和下划线 |
Value | String | 变量值 |
Secrets
| 参数 | 类型 | 说明 |
|---|---|---|
Name | String | 密钥名称,如 TCR_PASSWORD。构建容器中以 $SECRET_<NAME> 引用 |
Value | String | 密钥值 |
密钥加密存储,查询接口不返回明文。
响应参数
| 参数 | 类型 | 说明 |
|---|---|---|
BuildId | String | 构建 ID |
VersionName | String | 版本名称,如 my-vue-app-01-001 |
ServiceName | String | 服务名称 |
RequestId | String | 请求 ID,排查问题时提供 |
上传代码包
代码来源为压缩包时,分两步完成:
-
调用
DescribeCloudAppCosInfo,获取上传地址。参数 说明 EnvId环境 ID ServiceName服务名称 DeployType与创建时一致 Suffix文件后缀,如 .zip返回
UploadUrl、UploadHeaders和UnixTimestamp。 -
向
UploadUrl上传压缩包,请求头带上UploadHeaders。上传地址带签名,有效期有限,过期后重新获取。
调用 CreateCloudApp 时,Source.Type 填 zip,Source.CosTimestamp 填第 1 步返回的 UnixTimestamp。
查询构建状态和日志
构建状态
调用 DescribeCloudAppVersion,使用 BuildId 或 VersionName 查询。
| 参数 | 必填 | 说明 |
|---|---|---|
EnvId | 是 | 环境 ID |
ServiceName | 是 | 服务名称 |
DeployType | 是 | 部署类型 |
BuildId | 否 | 构建 ID |
VersionName | 否 | 版本名称 |
返回的 Status 为构建状态,Steps 为各步骤的执行状态。Resources 为本次部署涉及的资源列表。
构建日志
调用 DescribeCloudBaseRunBuildLog。
| 参数 | 类型 | 说明 |
|---|---|---|
EnvId | String | 环境 ID |
ServiceName | String | 服务名称 |
ServiceVersion | String | 版本名称 |
BuildId | Integer | 构建 ID |
Start | Integer | 日志偏移,用于分段拉取 |
接口定义见 查询构建日志。
示例
三步构建
{
"EnvId": "your-env-id",
"ServiceName": "my-vue-app",
"DeployType": "custom",
"Source": {
"Type": "git",
"Repo": "https://github.com/my-org/my-vue-app.git",
"Ref": "main",
"Channel": "github"
},
"Commands": {
"InstallCmd": "npm install",
"BuildCmd": "npm run build",
"DeployCmd": "tcb hosting deploy ./dist / -e your-env-id"
},
"NodeJsVersion": "22",
"Env": [
{ "Key": "NODE_ENV", "Value": "production" }
]
}
私有仓库
{
"EnvId": "your-env-id",
"ServiceName": "private-service",
"DeployType": "custom",
"Source": {
"Type": "git",
"Repo": "https://github.com/my-org/private-service.git",
"Ref": "release/v2.0",
"Channel": "github",
"IsPrivate": true
},
"Commands": {
"InstallCmd": "pnpm install --frozen-lockfile",
"BuildCmd": "pnpm run build",
"DeployCmd": "tcb deploy --yes"
}
}
自定义步骤:构建并推送镜像
{
"EnvId": "your-env-id",
"ServiceName": "go-api-service",
"DeployType": "custom",
"Source": {
"Type": "git",
"Repo": "https://gitlab.com/my-org/go-api.git",
"Ref": "master",
"Channel": "gitlab"
},
"CustomSteps": [
{ "Name": "build-binary", "Command": "go build -o bin/api ./cmd/api" },
{ "Name": "build-image", "Command": "docker build -t my-registry.com/go-api:latest ." },
{ "Name": "push-image", "Command": "docker login -u $REGISTRY_USER -p $SECRET_REGISTRY_PASSWORD my-registry.com && docker push my-registry.com/go-api:latest" }
],
"Env": [
{ "Key": "CGO_ENABLED", "Value": "0" },
{ "Key": "REGISTRY_USER", "Value": "myuser" }
],
"Secrets": [
{ "Name": "REGISTRY_PASSWORD", "Value": "<registry-password>" }
]
}
前后置命令
{
"EnvId": "your-env-id",
"ServiceName": "my-vue-app",
"DeployType": "custom",
"Source": {
"Type": "git",
"Repo": "https://github.com/my-org/my-vue-app.git",
"Ref": "main",
"Channel": "github"
},
"CustomSteps": [
{ "Name": "check-node", "Command": "node -v" }
],
"NodeJsVersion": "22",
"PreDeployCommand": "echo pre-deploy",
"PostDeployCommand": "echo post-deploy"
}
错误码
| 错误码 | 说明 |
|---|---|
InvalidParameter | 参数格式或类型错误,如 EnvId 缺失或非法 |
LimitExceeded.ErrNamespaceMaxLimit | 命名空间超过配额 |
LimitExceeded.ErrRepoMaxLimit | 镜像容器超过配额 |
ResourceNotFound | 资源不存在 |
FailedOperation | 操作失败 |
InternalError | 内部错误 |
其他公共错误码见 公共错误码。