Skip to main content

Declarative Deployment (tcb deploy)

Version Requirement

tcb deploy declarative orchestration is available since v3.8.0 and requires cloudbaserc.json v2.1.

tcb deploy reads cloudbaserc.json (v2.1) in the project root and orchestrates deployment of cloud functions, cloud apps, static hosting, gateway routes, and database migrations in dependency order — no need to call single-resource commands one by one.

Differences from Single-Resource Commands

Dimensiontcb deploytcb fn deploy / tcb hosting deploy
Config sourceOne cloudbaserc.json declares all resourcesEach command passes its own arguments
Orchestrationdatabase → functions → app → hosting → gateway auto-orderedSingle resource
DependenciesFunctions depend on new Schema (database first), gateway depends on functions/hostingNot aware
IdempotencyCloud existence check + local state snapshot; unchanged resources auto-skipFull execution every time
Overwrite confirmationConfirms before overwriting existing functions (--yes to proceed)--force

Complete Workflow

The standard end-to-end workflow for declarative deployment: Initialize Configuration → validate → preview changes → deploy.

StepCommandPurposeCompletion Signal
1 Initialize configtcb config initAuto-detects project resources (cloud function dirs / frontend framework / static hosting dirs) and interactively generates cloudbaserc.json (v2.1)Valid config created in the project root
2 Validate before deploytcb validateValidates schema version / envId / resource dirs / reference consistencyExit code 0, resource overview printed
3 Preview changestcb deploy --dry-runOutputs the resource-level change plan: field-level diffs (from → to), hosting file diffs — no actual deploymentChange plan matches expectations
4 Deploytcb deployOrchestrates deployment in database → functions → app → hosting → gateway orderDeployment succeeds, state snapshot generated

Quick Start

With cloudbaserc.json already created, run in the project root:

# Validate before deploy (recommended)
tcb validate

# Preview the change plan (no actual deployment)
tcb deploy --dry-run

# Deploy
tcb deploy
No cloudbaserc.json found?

If no config file exists, tcb deploy warns you about the missing file and guides you to run tcb config init to generate a declarative config template (cloud functions / static hosting / gateway one-click orchestration). It then continues with the traditional cloud app deployment flow, so existing behavior is unaffected.

tcb init vs tcb config init
  • tcb config init (recommended): auto-detects and generates a v2.1 declarative config — the first step of the complete workflow
  • tcb init: legacy template init command (deprecated, use tcb new <appName> [template] instead); generates a v2.0 config, which does not apply to declarative deployment (v2.1)

Minimal cloudbaserc.json (v2.1):

{
"envId": "your-env-id",
"version": "2.1",
"functions": [
{ "name": "pay-common", "type": "Event", "handler": "index.main" }
],
"hosting": [
{ "name": "web", "root": "web", "framework": "vite", "outputDir": "dist", "deployPath": "/web" }
],
"gateway": {
"routes": [
{ "path": "/api", "target": "function:pay-common" },
{ "path": "/web", "target": "hosting:web" }
]
}
}

Corresponding project structure:

project/
├── cloudbaserc.json
├── functions/
│ └── pay-common/
│ └── index.js
└── web/
└── dist/ # build output (or let tcb deploy build locally)
Directory Convention

See Project Directory Convention below for the full layout. Database migrations default to cloudbase/migrations/.

Deployment Flow

tcb deploy orchestrates in the following order (dependencies first):

database → functions → app → hosting → gateway

Overwrite Confirmation

  • Functions that already exist in the cloud (update scenario) are confirmed before overwriting
  • --yes proceeds directly; interactive mode confirms item by item
  • When no confirmation mechanism is provided, it conservatively skips (never overwrites production without consent)

Incremental Deployment

  • After the first successful deployment, a local .cloudbase/state.json fingerprint snapshot is generated
  • On subsequent deploys: hosting files with identical fingerprints and unchanged app configs are automatically skipped (no re-upload/re-build)
  • --refresh forces re-comparison against the cloud (drift detection)

Command Options

--dry-run

Outputs only the change plan (terraform plan mindset), without deploying:

tcb deploy --dry-run

Shows field-level changes (from → to), hosting file diffs, and database migration plans.

--only / --skip

Deploy only specified types / skip specified types:

tcb deploy --only=functions # deploy cloud functions only
tcb deploy --only=hosting,gateway # deploy hosting and gateway only
tcb deploy --skip=gateway # skip gateway

Available types: database / functions / app / hosting / gateway.

--mode / --env-id

Apply environment-specific configuration:

tcb deploy --mode=production # apply envOverrides.production + .env.production
tcb deploy --env-id=xxx # specify environment (highest priority)

--refresh

Ignore local state snapshot skip decisions and force re-comparison against the cloud (drift detection):

tcb deploy --refresh

--yes

Proceed with function overwrite updates directly (CI / AI Agent scenarios):

tcb deploy --yes

Concurrency (--concurrency)

Default 1 (strictly serial), consistent with historical behavior. When set, multiple resource instances of the same type are deployed in parallel; cross-type resources still follow the dependency order (database → functions → app → hosting → gateway) serially, without breaking dependencies.

tcb deploy --concurrency 3 # parallelize across functions/hosting sites, max 3 at a time
  • Applies only to "consecutive instances of the same type" (e.g., multiple hosting sites, multiple functions); functions vs hosting, hosting vs gateway always run serially.
  • Concurrency is capped at 20 to avoid excessive pressure on backend APIs.

Failure Interruption (--continue-on-error)

Default is fail-fast: if any resource fails to deploy, subsequent resources are interrupted and the process exits with a non-zero exit code (for CI/CD awareness). To "run through everything and view the failure count at the end", add --continue-on-error:

tcb deploy --continue-on-error # continue deploying the rest even if one resource fails

Exception: database failures always force interruption (regardless of --continue-on-error), because subsequent resources may depend on the newly created database schema.

Resource Configuration Overview

See the corresponding docs for full field details:

ResourceConfig fieldKey notesDocs
Database migrationsdatabasepostgresql only; migration files 14-digit-timestamp_name.sql, default dir cloudbase/migrations/; conflicts abort deploymentPostgreSQL Management
Cloud functionsfunctionsEvent / HTTP types; zip code or image deployment (buildStrategy); HTTP functions support public anonymous access and gatewayPath gateway routingFunction Configs · Deploying Functions
Cloud appappBuild path decided by framework: static direct upload / others cloud buildApplication Deployment
Static hostinghostingArray of multiple sites; local build (install + build) then uploadStatic Website Hosting
Gateway routesgateway.routestarget: function:<name> / hosting:<name>; pathRewrite auto-generatedConfiguration File - Gateway
Environment overridesenvOverridesMerged by --modeConfig File
Function target type

The gateway route target: function:<name> supports two function types:

  • HTTP type (type: "HTTP") → created as a WEB_SCF route
  • Event type (regular function) → created as an SCF route (verified to work; the gateway wraps the HTTP request as an event and forwards it to the function)

The CLI automatically queries function details to determine the type; both types can serve as gateway targets.

Project Directory Convention

Recommended layout (using vibe-app as an example):

vibe-app/
├── cloudbaserc.json # declarative config (core contract, envId/version 2.1)
├── .env # secrets (not in Git; reads .env.<mode> when --mode <mode>)
├── .env.example # secrets template (in Git)
├── cloudbase/migrations/ # database migrations (SQL, default dir)
│ ├── 20260101120000_init.sql
│ └── 20260102150000_add_users.sql
├── functions/ # cloud function code (functionRoot defaults to ./functions)
│ ├── task-runner/ # Event function: exports.main(event, context)
│ └── api-server/ # HTTP function: requires scf_bootstrap
├── web/ # frontend code (pointed by hosting[].root)
└── Dockerfile # optional, for image deployment (inside function dir)

Path resolution rules:

ResourceConfig fieldDefault / resolution
Database migration dirdatabase.migrationscloudbase/migrations/ (relative to project root)
Function rootfunctionRootfunctions/
Function code dirdir / functionRoot+nameExplicit dir{cwd}/{dir} (independent of functionRoot); otherwise {cwd}/{functionRoot}/{name}
Frontend sitehosting[].rootDirectory relative to cloudbaserc

FAQ

1. gateway.routes validation failure (should NOT have additional properties)

Schema v2.1 does not allow extra fields. For example, cdnType is not a valid route field — remove it; use accessType (DIRECT / CDN / CUSTOM / EO) to control CDN access:

{ "path": "/web", "target": "hosting:web", "accessType": "DIRECT" }

2. HTTP function dependency installation rules

Function typeRuntimeDependency installation
EventAnyCloud-side install (default)
HTTPNode.jsCloud-side install (default)
HTTPNon-Node.js (Python/Php/Java/Go)Must install locally and upload with the code

For HTTP non-Node.js functions, ensure dependencies are installed locally (e.g., Python pip install into the function directory).

3. Will existing functions be overwritten?

Functions that already exist (update scenario) require confirmation by default; --yes proceeds. Declarative deployment semantics align with tcb fn deploy --force.

4. Domain-level fields do not take effect on already-bound domains

certId / protocol / accessType are domain-level fields (shared by all routes under the same domain). When creating routes on an already-existing domain, these fields do not override the domain's original values (e.g. if the domain is already bound with HTTP_AND_HTTPS, setting protocol: "HTTPS" has no effect) — this is the platform's safety behavior to avoid affecting other business routes under the same domain. They only take effect when the domain is first created.

5. Gateway route idempotency semantics

tcb deploy gateway routes converge idempotently (create / update / skip):

  • Route does not exist → create (create)
  • Route exists and the explicitly declared fields match → skip (skip)
  • Route exists but explicitly declared fields differ → update (update, calls modifyHttpServiceRoute)

Only explicitly declared fields are compared (enableAuth / enablePathTransmission are compared only when explicitly configured; qpsPolicy / pathRewrite are compared only when the local value is present), and undeclared fields do not override the cloud configuration. Duplicate paths are not treated as errors (unlike the INVALID_PARAM of imperative tcb routes add). See Configuration File - Gateway for the authoritative field definitions.

References