Skip to main content

tcb hosting deploy

Uploads a local file or directory to the static website. Without localPath, every file under the current directory is uploaded.

When your project has a build step, use Application deployment; it builds first. This command only uploads the output you already produced.

Usage​

tcb hosting deploy [localPath] [cloudPath] [options]

Options​

OptionRequiredDescriptionDefault
<localPath>NoLocal file or directory, resolved against the current directoryCurrent directory
<cloudPath>NoTarget path in the cloudRoot directory
-e, --env-id <envId>YesEnvironment ID—
--ignore <patterns>NoComma-separated patterns to skip; only applies to directory deploys—
--enable-git-ignoreNoMerge the rules in the project .gitignoreNot merged
--entry <files>NoComma-separated entry files relative to the upload directory, uploaded last after all other assetsDetected index.html files
--verifyNoVerify remote files against the local output after publishing—
--safeNoBack up the remote files before publishing and roll back on failure—
--pruneNoRemove remote files that are not part of this release—
--concurrency <number>NoUpload concurrency, lower it for large files or slow networks20
--retry-count <number>NoRetry attempts for failed uploads2
--retry-interval <ms>NoInterval between retries, in milliseconds1000

For how --verify, --safe, and --prune work together, see Consistent release. Ignore patterns follow the same syntax and precedence as tcb app deploy, see app deploy ignore rules.

Examples​

# Deploy every file under the current directory
cd docs
tcb hosting deploy -e envId

# Upload a local index.html to the cloud root
tcb hosting deploy ./index.html -e envId

# Upload to a specific cloud path, static/index.js
tcb hosting deploy ./static/index.js static/index.js -e envId

# Skip files on directory deploys and merge .gitignore
tcb hosting deploy ./dist -e envId --ignore "*.map,.DS_Store" --enable-git-ignore

# Large files or slow networks: lower concurrency and retry more
tcb hosting deploy ./dist --concurrency 5 --retry-count 3

Consistent release​

Adding any of --verify, --safe, or --prune to a directory deploy turns it into a consistent release: scan local files into a manifest, back up the remote files, upload, verify, then remove remote leftovers. The last three steps run only when the matching option is set.

OptionDescription
--verifyCompare remote files with the local build and check size and MD5
--safeBack up remote files to .cloudbase-backup/<timestamp>/ before uploading, and roll back when the upload or verification fails
--pruneAfter a successful release, delete files under the current cloudPath that are missing from the local manifest

--prune asks for confirmation; add --yes to skip it. It only touches files under the current cloudPath prefix, so pair it with --safe.

# Verify the release
tcb hosting deploy ./dist --verify

# Safe release with automatic rollback
tcb hosting deploy ./dist --safe

# Safe release that also removes remote leftovers
tcb hosting deploy ./dist --safe --prune --yes

# Upload entry files last
tcb hosting deploy ./dist --entry index.html,admin/index.html

Backups are not cleaned up automatically. Delete them manually once the release is confirmed.

Declarative deployment​

Configure the hosting field in cloudbaserc.json and deploy several sites at once with tcb deploy. Since CLI v3.8.2, build and deploy are separate steps:

  1. Build: run tcb app build to execute buildCommand locally and produce the output; it installs no dependencies and uploads nothing
  2. Deploy: run tcb deploy to upload the output and orchestrate the remaining resources

When buildCommand is set, tcb deploy no longer builds locally. A missing output directory fails with a prompt to run tcb app build first. Pure static sites without buildCommand upload outputDir directly.

FieldTypeRequiredDefaultDescription
nameStringYes—App name, unique within the config file, referenced by gateway.routes[].target: hosting:<name>
rootStringNo.App root directory relative to cloudbaserc.json, for monorepos
frameworkStringNostaticreact, vue, vite, vite-react, vite-vue, next, nuxt, angular, static, or custom. Detected from root/package.json when unset; static and custom mean pure static with no build
installCommandStringNo—Install command. The CLI no longer runs it locally, so install dependencies yourself
buildCommandStringNo—Build command. When set, tcb app build runs the local build first; when empty and no framework is detected, outputDir is uploaded as pure static
outputDirStringNodistBuild output directory relative to root. Defaults to root for pure static sites
deployPathStringNo/Path prefix for the deployment; give each site a different one. A missing leading / is added automatically and reported in the terminal
envVariablesObjectNo—Variables injected into process.env at build time, non-sensitive only
ignoreString / ArrayNo—Glob patterns to skip during upload, such as ["node_modules", "*.log"]

A framework of vite, vite-react, or vite-vue defaults to the build command npm run build and the output directory dist.

{
"hosting": [
{
"name": "web",
"root": "./packages/web",
"framework": "vite",
"buildCommand": "npm run build",
"outputDir": "dist",
"deployPath": "/web"
}
]
}

Notes:

  • A deployPath containing whitespace, shell special characters, or ../, or starting with -, is rejected
  • deployPath values must be unique and must match the corresponding gateway.routes[].path
  • envVariables is injected into the build, not into the runtime environment

Paths and limits​

Path syntax​

  • localPath: a local path using the system separator. On Windows that is \, for example .\static\index.js
  • cloudPath: a path relative to the cloud root, always using /, for example static/css/index.css

Enabling the service​

Static website hosting must be enabled first. Platform-edition accounts get hosting resources provisioned with the environment; regular accounts enable it manually.

When it is not enabled, the tcb hosting commands only query the status and never enable it, so they fail immediately. Run tcb hosting detail and follow the prompt, or enable it in the CloudBase console.

A newly enabled service reports “initializing” and rejects uploads. The command polls every 5 seconds for up to about 6 minutes; run it again after a timeout.

Upload limits​

  • A single file can be up to 50 TB, and the number of files is unlimited
  • Uploads retry twice by default, and a transient socket hang up recovers automatically
  • On slow networks or with large files, lower --concurrency (default 20), or raise --retry-count (default 2) and --retry-interval (default 1000 ms)
  • If uploads are still unstable, set COS_SDK_KEEPALIVE=false to disable SDK keep-alive connections

Other​

  • Vue Router history mode requires setting the error page to the entry index.html in the static website console
  • The default access domain is shown in the console. Custom domains require an ICP filing