provisionCvm
POST /cvms
Provisions a new CVM. This is the first phase of the two-phase deployment flow — call commitCvmProvision to finalize.
Parameters:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | CVM name (5-63 chars, must start with a letter) |
compose_file | object | Yes, unless compose_file_raw is sent | Compose file configuration (see below) |
instance_type | string | No | Instance type (default: "tdx.small") |
node | string | No | Physical node name for deployment |
region | string | No | Region filter |
image | string | No | OS image name |
disk_size | number | No | Disk size in GB |
kms | string | No | KMS type: "PHALA" (default), "ETHEREUM", or "BASE" |
kms_contract | string | No | KMS contract address (on-chain KMS only) |
env_keys | string[] | No | Allowed environment variable keys |
nonce | number | No | Nonce for deterministic app_id (PHALA KMS only) |
app_id | string | No | Expected app_id (must match nonce) |
listed | boolean | No | List CVM in public directory |
init_scripts | ("docker_cleanup" | "env_merge")[] | No | Platform init scripts the CVM runs on every boot: docker_cleanup (needs dstack OS 0.6.x, ext4 storage and the docker-compose runner) and env_merge (dstack OS 0.6.0 or newer, available on request). The list is the whole set; Phala Cloud runs them in a fixed order, docker_cleanup first. See Init scripts. |
launch_token | string | No | Launch token, at least 32 bytes, that the CVM must have on every boot. See Launch Token. |
generate_launch_token | boolean | No | Have Phala Cloud generate the launch token for a new app, or use the app’s existing token. A new token is returned once, as launch_token in the commit response. |
annotations | Record<string, string> | No | Host-side settings for tools on the node, not measured. Needs a feature flag (ERR-03-049 without it) and dstack VMM 0.6.1 or newer on the node (ERR-03-050). See Annotations. |
compose_file_raw | string | No | A whole app-compose JSON file as one string, sent instead of compose_file. Needs a feature flag. Phala Cloud parses it with the same rules and writes it the same way, so the compose hash comes from that output, not from your bytes. See Raw app-compose input. |
compose_file object:
| Field | Type | Required | Description |
|---|---|---|---|
docker_compose_file | string | Yes | Docker Compose YAML content |
allowed_envs | string[] | No | Env var keys the CVM may receive |
pre_launch_script | string | No | Script to run before containers start |
gateway_enabled | boolean | No | Enable gateway/proxy |
kms_enabled | boolean | No | Enable KMS integration |
public_logs | boolean | No | Make container logs public |
public_sysinfo | boolean | No | Make system info public |
ProvisionCvm
| Field | Type | Description |
|---|---|---|
compose_hash | string | Hash of the compose configuration — pass to commitCvmProvision |
app_id | string? | App ID (only for PHALA KMS) |
app_env_encrypt_pubkey | string? | Encryption public key (only for PHALA KMS) |
kms_id | string? | KMS instance ID |
kms_info | KmsInfo? | KMS details |
device_id | string? | Device ID for on-chain KMS |
fmspc | string? | FMSPC of the selected node |
os_image_hash | string? | OS image hash |
instance_type | string? | Selected instance type |
node_id | number? | Selected node ID |
import { createClient, encryptEnvVars, parseEnvVars } from "@phala/cloud";
const client = createClient();
const provision = await client.provisionCvm({
name: "my-app",
instance_type: "tdx.small",
compose_file: {
docker_compose_file: composeYaml,
allowed_envs: ["API_KEY", "SECRET"],
},
});
// PHALA KMS returns app_id and pubkey directly
const encrypted = await encryptEnvVars(envVars, provision.app_env_encrypt_pubkey!);
await client.commitCvmProvision({
app_id: provision.app_id!,
compose_hash: provision.compose_hash,
encrypted_env: encrypted,
env_keys: ["API_KEY", "SECRET"],
});
import { deployAppAuth } from "@phala/cloud";
// Step 1: Provision — reserves the CVM but does not start it
const provision = await client.provisionCvm({
name: "my-app",
compose_file: { docker_compose_file: composeYaml },
kms: "ETHEREUM",
});
// Step 2: Deploy an AppAuth contract to obtain an app_id
const deployed = await deployAppAuth({
chain: provision.kms_info!.chain,
rpcUrl: "https://...",
kmsContractAddress: provision.kms_info!.kms_contract_address,
privateKey: "0x...",
deviceId: provision.device_id,
composeHash: provision.compose_hash,
});
// Step 3: Commit — finalizes the deployment and starts the CVM
await client.commitCvmProvision({
app_id: deployed.appId,
compose_hash: provision.compose_hash,
kms_id: provision.kms_id!,
contract_address: deployed.appAuthAddress,
deployer_address: deployed.deployer,
});
The combined size of
docker_compose_file and pre_launch_script must not exceed 200KB.safeProvisionCvm
Safe variant that returns aSafeResult<ProvisionCvm> instead of throwing on errors.
const result = await client.safeProvisionCvm({ ... });
if (result.success) {
console.log(result.data.compose_hash);
} else {
console.error(result.error);
}

