Declarative Deployment Orchestrator
Declarative deployment orchestration (app.deployOrchestrator) is available since v5.1.0, corresponding to CLI tcb deploy (≥ v3.8.0).
DeployOrchestrator provides one-shot orchestrated deployment: reads a single cloudbaserc.json (v2.1) config and deploys all resources in dependency order (database → functions → app → hosting → gateway), with dry-run plan preview, function overwrite confirmation, and local state snapshot for true incremental skips.
Access via app.deployOrchestrator (same implementation as CLI tcb deploy — capability is hosted in manager-node).
manager-node does not bundle any interactive UI. Function overwrite confirmation is fully externalized: pass yes: true to proceed, or inject a confirmUpdate callback to decide per item.
deployPlan
1. Description
Computes the deployment plan (dry-run) without performing any actual deployment.
Signature: app.deployOrchestrator.deployPlan(options): Promise<IDeployPlanItem[]>
2. Parameters
| Field | Required | Type | Description |
|---|---|---|---|
| config | Yes | Record<string, any> | Parsed cloudbaserc config (envOverrides already merged) |
| envId | Yes | String | Environment ID |
| only | No | ResourceType[] | Deploy only these types |
| skip | No | ResourceType[] | Skip these types |
| refresh | No | Boolean | Ignore local state skip decisions, force cloud comparison (drift detection) |
| cwd | No | String | Project root, default process.cwd() |
ResourceType: database / functions / app / hosting / gateway
3. Returns
IDeployPlanItem[]:
| Field | Type | Description |
|---|---|---|
| type | ResourceType | Resource type |
| name | String | Resource name |
| status | String | create / update / skip / conflict (database, aborts) / deploy |
| action | String | Human-readable action |
| changes | Array | Field-level changes (from → to) |
| fileDiff | Object | hosting file diff (added/modified/deleted + totalChanged) |
4. Example
import CloudBase from '@cloudbase/manager-node'
const app = CloudBase.init({
secretId: 'Your SecretId',
secretKey: 'Your SecretKey',
envId: 'Your envId'
})
const plan = await app.deployOrchestrator.deployPlan({
config: { envId: 'xxx', functions: [{ name: 'fn-a' }] },
envId: 'xxx',
cwd: process.cwd()
})
for (const item of plan) {
console.log(`[${item.type}] ${item.name}: ${item.action}`)
}
deploy
1. Description
Executes the deployment (with overwrite confirmation).
Signature: app.deployOrchestrator.deploy(options): Promise<IDeployResult>
2. Parameters
| Field | Required | Type | Description |
|---|---|---|---|
| config | Yes | Record<string, any> | Parsed cloudbaserc config |
| envId | Yes | String | Environment ID |
| dryRun | No | Boolean | When true, only outputs the plan without deploying |
| yes | No | Boolean | Proceed with existing function (update) overwrites (AI Agent / CI) |
| confirmUpdate | No | (item) => Promise<boolean> | Callback per update item; return true to execute / false to skip |
| only / skip | No | ResourceType[] | Type filters |
| refresh | No | Boolean | Force cloud comparison (drift detection) |
| cwd | No | String | Project root |
| log | No | Object | Log callbacks (info/success/warn/error) |
3. Returns
IDeployResult:
| Field | Type | Description |
|---|---|---|
| plan | IDeployPlanItem[] | Full deployment plan |
| results | Array | Each item: { type, name, ok, url?, error?, reason? } |
results semantics:
ok: true→ success;urlis the access URL (if any)ok: false+error→ deployment failure reasonok: false+reason: 'no-confirm'→ no confirmation mechanism, conservatively skipped (never overwrites production)ok: false+reason: 'skipped-by-user'→ user cancelled the overwrite
4. Example
import CloudBase from '@cloudbase/manager-node'
const app = CloudBase.init({
secretId: 'Your SecretId',
secretKey: 'Your SecretKey',
envId: 'Your envId'
})
// AI Agent / CI: proceed with all overwrites
const result = await app.deployOrchestrator.deploy({
config: { envId: 'xxx', functions: [{ name: 'fn-a' }] },
envId: 'xxx',
yes: true,
cwd: process.cwd()
})
if (result.results.every(r => r.ok)) {
console.log('Deploy complete')
} else {
for (const r of result.results.filter(r => !r.ok)) {
console.error(`[${r.type}] ${r.name} failed: ${r.error || r.reason}`)
}
}
Notes
Idempotency and True Incrementality
- Functions: cloud existence check (
ListFunctions) → create / update; no local hash - hosting: local
.cloudbase/state.jsonfingerprint snapshot; skip when identical - app: local state config snapshot; skip when identical
refresh: trueforces re-comparison against the cloud, ignoring the local snapshot
HTTP Cloud Function Image Deployment
HTTP functions under functions can use the top-level buildStrategy to select an image deployment method:
image: Uses the existing image specified byimageConfig.imageUri.local: Builds and pushes the image locally with Docker.cloud: Uploads the build context and lets CloudApp build and push the image in the cloud.
Image fields are under imageConfig, while build fields are under imageConfig.build. imageConfig.imageType supports personal and enterprise: personal builds must explicitly provide imageConfig.build.registryCredential.username/password; enterprise deployments can specify a TCR instance through registryId, or discover it automatically when omitted. When omitted, namespace and repository are filled by the deployer from the environment ID and function name.
The deployment flow sets the image function runtime to CustomImage and defaults to port 9000, Dockerfile, and the linux/amd64 build platform; explicitly configured values take precedence. local builds also perform pre-deployment checks for the Docker CLI, daemon, and Buildx, and support marking a cloud-build fallback through imageConfig.localFallback: "cloud".
database Conflict Aborts
When a database migration has conflicts, deployment aborts (later resources may depend on the new Schema). The plan item appears with status: 'conflict'.
Version Mapping
| manager-node | CLI | Description |
|---|---|---|
| ≥ v5.1.0 | ≥ v3.8.0 | Declarative deployment orchestration available |