Deploying

Deploy functions to Clusterbase — preview and production deployments, promote, and undeploy.

ccp deploy bundles your code, uploads it, and activates a deployment on Clusterbase's serverless runtime.

Deploy to Production

ccp deploy --prod
# ◼ Building Function...
# ◼ Creating Deployment...
# ◼ Uploading code...
# ◼ Deploying...
# ◼ my-app deployed!
# › https://my-app.clusterbase.dev

The --prod flag (alias: --production) makes this the active production deployment, served at https://{function-name}.clusterbase.dev.

Preview Deployments

Without --prod, you get a preview deployment with its own URL:

ccp deploy
# ◼ my-app deployed!
# › https://abc123.clusterbase.dev

Preview deployments are useful for testing changes before promoting to production.

Promote a Preview

Promote any preview deployment to production:

ccp promote <deployment-id>

This swaps the production deployment to the given deployment ID without redeploying.

Undeploy

Remove a specific deployment:

ccp undeploy <deployment-id>

List Deployments

ccp list        # or: ccp ls

Inside a linked project, shows all deployments for that function with their IDs, status, and timestamps.

Run outside a project (or in one that hasn't been deployed yet) and ccp ls instead lists every function in the organization — resolve the org with --org-id, the project config, or the interactive picker. See Functions → Managing Functions.

Deploy Options

FlagDescription
--prod / --productionDeploy as the production deployment
--public-dir <path>Include a public directory for static assets
--client <path>Include a client-side script
--org-id <id>Organization ID — skips the org selection prompt
--function-id <id>Function ID — skips the function selection / creation prompt
-y / --yesSkip prompts; if unlinked, auto-create + link a function named after the project (single-org auto-picks; pass --org-id or set CCP_ORG_ID for multi-org)
--register-redirect-uriRegister this deploy's host as an OIDC redirect URI on the linked client. Production deploys already do this automatically; pass the flag to opt a preview deploy in (see OIDC → Auto-register on Deploy)
<path>Path to a file or directory (defaults to current directory)

How It Works

  1. Bundle — your TypeScript/JavaScript is compiled into a single ESM bundle
  2. Upload — the bundle (and any assets) are uploaded to Clusterbase's storage
  3. Activate — Clusterbase publishes the new deployment to the runtime
  4. Route — routes are created for {function-name}.clusterbase.dev and {deployment-id}.clusterbase.dev
  5. Serve — the serverless runtime creates a V8 isolate and starts handling requests

Client Bundle and CSS

When client is set (e.g. src/main.tsx) under [serverless] in cluster.toml, that entry is bundled for the browser and served at /{stem}.js (main.js). CSS imported from the client (import "./App.css" — multiple files, @import, and *.module.css all work) is bundled into a single /{stem}.css (main.css).

The server entry (your handler) may import CSS too — that's how server-side rendering shares a component with the client. Stylesheets reached from the handler are discarded (the client is the sole producer of /{stem}.css), so import the same styles from the client entry, which SSR does naturally by sharing the component. Two things to watch for:

  • With no client entry there's nothing to serve the stylesheet, so a CSS import from the handler is still a deploy error.
  • *.module.css imported from the handler only warns, rather than erroring: class names still resolve correctly, but the client and server bundles are built as separate graphs, so generated class names can disagree if two *.module.css files share a basename. Prefer plain CSS, or unique basenames, for components shared between server and client.

First Deploy

On your first deploy, if .ccp/config.json doesn't have a function_id, CCP resolves one for you:

  • Interactive: you're prompted to select an organization, then link an existing function or create a new one.
  • Headless (no TTY or --yes): CCP auto-creates and links a new function named after your project (its package.json name, else the directory), with no prompts. A single-org account needs no flags; with multiple orgs pass --org-id or set CCP_ORG_ID (otherwise it errors listing them).

Either way the function ID is saved to .ccp/config.json for future deploys.

Build Without Deploying

To test the build step without deploying:

ccp build

This runs the bundler and reports any errors, but doesn't upload or activate anything.

Headless / CI Deploys

For CI pipelines and AI agents, set CCP_HEADLESS=1 and deploy never blocks on a prompt. On a single-org account, the first deploy needs no flags at all — it auto-creates the function:

export CCP_HEADLESS=1
ccp deploy --prod

With multiple organizations, name the target so CCP doesn't have to guess:

ccp deploy --prod --org-id "$ORG_ID"

Or export CCP_ORG_ID="$ORG_ID" once and every org-scoped command resolves the org without the flag.

To deploy to a pre-existing function (skip creation entirely), pass both ids:

ccp deploy --prod --org-id "$ORG_ID" --function-id "$FUNCTION_ID"

After the first deploy the IDs are written to .ccp/config.json, so subsequent deploys on that machine reuse them with no flags. That file is gitignored, so a fresh clone or a new CI runner won't have it — pass both ids again there. ccp link --org-id <id> --function-id <id> seeds the config without uploading code, when you want to link separately from the first deploy.

See Headless Mode for the full reference.

On this page