Skip to main content
Replication creates a new CVM instance with the same configuration as an existing source CVM. Use it to scale out, move a workload to a different node, or split traffic across replicas in different regions. This guide focuses on the two workflows most users should use: the Phala Cloud dashboard and the phala CLI. An API reference is included at the end for programmatic integrations.

Mental Model

A replica is a new, independent CVM instance provisioned from a source CVM. It gets its own vm_uuid, endpoint, and attestation. It does not share storage, memory, or running state with the source. Copied from source (you do not re-specify these):
  • The compose file and pre-launch script (same compose_hash)
  • The application ID (all replicas of an app share one app_id)
  • The KMS type and chain
  • The encrypted environment variables
Things you can change at replication time:
  • The target node (pin the replica to a specific node, or let the platform pick one)
  • The encrypted environment variables (optional override — pass a new encrypted blob to replace the inherited one)
Not carried over:
  • Running processes, in-memory state
  • Contents of persistent volumes and any data written at runtime
  • Active network connections

The three replication workflows

Which workflow applies depends on the source CVM’s KMS setup. You do not pick it — it is determined by how the source was deployed.
WorkflowApplies whenWhat you do
SimpleSource uses Cloud KMS or no KMSOne step: request the replica and wait for it to come up.
Onchain, auto-registeredSource uses Onchain KMS and the DstackApp owner is an EOA with an accessible private keyThe CLI detects missing on-chain registrations, signs addComposeHash / addDevice with the provided key, then creates the replica.
Onchain, manual approvalSource uses Onchain KMS and the DstackApp owner is a Safe, timelock, or DAOPrepare the replica, collect the on-chain payload, obtain multisig approval, then commit.
Onchain KMS adds gates because the DstackApp contract — not Phala Cloud — decides which compose hashes and devices are allowed to run under the app’s identity. If the new replica lands on a node whose device is not already allowlisted, someone has to sign addDevice before the KMS will release keys. See Deploying with Onchain KMS for the full model.

Prerequisites

Before replicating:
  • The source CVM exists in your current workspace. It can be running or stopped.
  • The target node (if you pin one) is deployable for your workspace, has the required OS image, and has enough vCPU, memory, and disk.
  • Your workspace has enough credit to cover the new instance. Replicas are billed like any other CVM.
For Onchain KMS workflows only:
  • Gas in your signing wallet on the chain the DstackApp lives on (typically Base — 0.001 ETH is plenty for the first few transactions).
  • An RPC URL for that chain. The CLI uses a default public endpoint, or you can pass --rpc-url / set ETH_RPC_URL.
  • Either a private key (for auto-registration) or a multisig wallet (for manual approval).

Replicate from the Dashboard

The dashboard wraps replication in a single “Scale” action on the app detail page. It is the fastest way to add replicas interactively.

Steps

  1. Open the app detail page for the application you want to scale.
  2. Click Scale to open the Scale dialog. The dialog shows the current list of replicas and lets you add or remove instances.
  3. Pick a source configuration. If your app has multiple live configurations (different compose hashes), choose the one you want to replicate. If there is only one, the dashboard selects it automatically.
  4. Choose a target node. Leave it on Auto to let the platform schedule the replica, or pick a specific node from the list. The list is filtered to nodes your workspace can deploy to.
  5. Set the number of replicas to add. Use the + / controls, then click the add button.
  6. The dashboard creates replicas one by one and shows their status as they provision.

When the dashboard prompts for on-chain action

If the source uses Onchain KMS and the target node’s device is not yet allowlisted, the Scale dialog warns you before creating the replica. You then have two options:
  • Approve from the dashboard with a connected wallet. The dashboard walks you through signing addDevice (and addComposeHash if needed) using the wallet connected to the app. This is the recommended path when the DstackApp owner is an EOA you control.
  • Approve externally. If the owner is a Safe or another contract, use the CLI’s manual workflow described below to obtain a commit token, sign on-chain through your multisig, then commit the replica.

Replicate with the CLI

The CLI is the right tool for scripting, CI/CD, and any workflow that does not start from the dashboard. It also exposes the lower-level prepare / commit flow used for multisig-gated apps. Install or update the CLI before starting:
npm install -g phala
phala login

Basic replication

Replicate a CVM to a specific node:
phala cvms replicate <cvm-id> --node-id prod6
--node-id accepts either a numeric node ID or a node name as shown in phala nodes ls — for example prod6, prod7, or use2. Ambiguous names are rejected rather than guessed, so if a name matches more than one node the CLI asks you to use the numeric ID instead. Omit --node-id to let the backend schedule the replica on any node with capacity and a compatible image:
phala cvms replicate <cvm-id>
<cvm-id> can be a CVM UUID, an app_id, or a unique CVM name. Prefer UUIDs in scripts — names can collide and app_id is ambiguous when an app has more than one live configuration (see Multi-instance apps below). On success the CLI prints the new replica’s UUID, node, and dashboard URL:
Source CVM ID:   app_abc123
Team:            my-workspace
CVM UUID:        550e8400-e29b-41d4-a716-446655440000
App ID:          0x1234...
Name:            my-app-replica-1
Status:          provisioning
Node:            prod6 (ID: 5)
vCPUs:           2
Memory:          4096 MB
Disk Size:       40 GB
App URL:         https://cloud.phala.com/my-workspace/apps/0x1234.../instances/550e8400...

Replicating with new environment variables

By default the replica inherits the source CVM’s encrypted environment. See Environment Variables for the full encryption model and the rules around allowed_envs. To change an env var on the replica — for example, to give a staging replica a different database URL — pass --env-file:
phala cvms replicate <cvm-id> --node-id prod6 --env-file .env.prod
The CLI:
  1. Parses the env file locally.
  2. Fetches the CVM’s per-application encryption public key from the backend.
  3. Encrypts each env var with that key.
  4. Sends only the ciphertext to the replicate endpoint.
Plaintext env values never leave your machine. Only the running CVM, after the KMS releases its keys, can decrypt them. Env var names you pass with --env-file must already appear in the app’s allowed_envs list — the list is fixed by the compose hash, so replication cannot introduce new names.

Multi-instance apps

When an app has multiple live CVMs with different compose hashes — for example, a canary deployment alongside the stable version — the CLI needs to know which configuration you want to replicate. Running the basic command with just the app_id fails:
$ phala cvms replicate app_abc123
Error: ERR-03-009 — This app has multiple live CVM instances.
       Please specify compose_hash to choose which revision to replicate.
Two ways to fix it:
  • Point at a specific source instance by UUID. The UUID uniquely identifies one compose hash.
    phala cvms replicate 550e8400-e29b-41d4-a716-446655440000 --node-id prod6
    
  • Pass --compose-hash explicitly. Look up the compose hash of the configuration you want (from the dashboard or phala cvms list) and pass it on the command line:
    phala cvms replicate app_abc123 --compose-hash 0xabcd... --node-id prod6
    

Onchain KMS: auto-registration

When the source CVM uses Onchain KMS and you own the DstackApp through an EOA, you can register and replicate in one command by passing a private key. The CLI detects whether the target node’s device and the compose hash are already allowlisted and only writes the transactions that are missing.
export PRIVATE_KEY=0x...
export ETH_RPC_URL=https://base-mainnet.example.com

phala cvms replicate <cvm-id> \
  --node-id prod6 \
  --private-key $PRIVATE_KEY \
  --rpc-url $ETH_RPC_URL
The sequence is:
  1. The backend prepares the replica and computes the compose_hash and the target node’s device_id.
  2. The CLI reads the DstackApp contract to see which registrations are missing.
  3. If the device is not allowlisted, the CLI calls addDevice and waits for confirmation.
  4. If the compose hash is not allowlisted, the CLI calls addComposeHash and waits for confirmation.
  5. The CLI commits the prepared replica, the backend creates the instance, and the replica boots.
If everything is already registered, the CLI skips straight to step 5 and the replica comes up immediately.

Onchain KMS: manual approval (multisig)

When the DstackApp owner is a Safe, a timelock, or any other contract that cannot sign from the CLI, use the prepare + commit flow. Step 1. Prepare. Ask the backend to reserve the replica and emit the on-chain payload:
phala cvms replicate <cvm-id> --node-id prod6 --prepare-only
The command does not create the replica. Instead it prints a commit token and the values that need to be authorized on-chain:
CVM replica prepared successfully (pending on-chain approval).

Compose Hash:    0xabcd1234...
App ID:          0x1234...
Device ID:       0xdevice...
Commit Token:    prep_token_xyz...

On-chain Status:
  Compose Hash:  NOT registered
  Device ID:     NOT registered

To complete the replica after on-chain approval:
  phala cvms replicate <cvm-id> \
    --commit \
    --token prep_token_xyz... \
    --compose-hash 0xabcd1234... \
    --transaction-hash <tx-hash>
The commit token is valid for 14 days. Save it somewhere your approvers can reach. Step 2. Sign on-chain. From your Safe (or whichever contract owns the DstackApp), call the missing writes on the DstackApp address printed above. Typically:
  • addComposeHash(0xabcd1234...) — if the Compose Hash line above shows NOT registered.
  • addDevice(0xdevice...) — if the Device ID line shows NOT registered.
Submit the transaction(s) through the Safe UI and wait for execution. Record the final transaction hash. Step 3. Commit. Pass the commit token, compose hash, and transaction hash back to the CLI:
phala cvms replicate <cvm-id> \
  --commit \
  --token prep_token_xyz... \
  --compose-hash 0xabcd1234... \
  --transaction-hash 0x5678...
If both writes are already on-chain and you just want to finalize, pass --transaction-hash already-registered. The backend re-reads the contract, verifies the state, and creates the replica. See Multisig and Governance for guidance on structuring the Safe ownership itself.

API Reference

For programmatic integrations — custom portals, CI systems, or orchestration that cannot shell out to the CLI — Phala Cloud exposes the replicate endpoints directly. Prefer the dashboard or CLI for interactive use; the raw API gives you no convenience on top of what the CLI already does.

POST /cvms/{cvm_id}/replicas

Create a replica from a source CVM.
FieldLocationRequiredDescription
cvm_idpathyesSource CVM identifier. UUID, app_id, or unique name.
node_idbodynoNumeric target node ID. Omit to let the backend pick. The API only accepts numeric IDs; name resolution (e.g. prod6) is a CLI feature.
compose_hashbodynoExplicit compose hash. Required when the source app has more than one live configuration.
encrypted_envbodynoHex-encoded encrypted env blob. Omit to inherit the source’s env.
X-Prepare-OnlyheadernoSet to true to prepare the replica without creating it, for the manual approval flow.
On success the response is a VM object representing the new replica. On Onchain KMS prerequisites failure the response is HTTP 465 with a structured body containing commit_token, compose_hash, device_id, and onchain_status; use those fields as inputs to the commit endpoint after completing on-chain approval.

POST /apps/{app_id}/cvms/{vm_uuid}/replicas

Alternative form that takes the app and source instance UUIDs in the URL. Same request body and response shape as the CVM-scoped endpoint. Use this when your integration already tracks (app_id, vm_uuid) pairs.

POST /cvms/{vm_uuid}/commit-replica

Finalize a replica prepared with X-Prepare-Only: true.
FieldRequiredDescription
tokenyesCommit token from the prepare response.
compose_hashyesThe same compose hash returned during prepare.
transaction_hashyesOn-chain transaction hash for the registration write, or "already-registered" when the prerequisites were met before commit.
The response is the same VM object you would get from a direct replicate call.

Errors

Replicate calls share the same structured error envelope as the rest of the Phala Cloud API. Common codes you may hit during replication:
CodeMeaning
ERR-01-005Onchain KMS requires compose hash or device registration (HTTP 465). Use auto-registration or the prepare + commit flow.
ERR-02-003 / ERR-02-004 / ERR-02-005Target node is out of vCPU, memory, or slots. Drop --node-id or pick a different node.
ERR-03-006The source CVM’s OS image is not available on the target node.
ERR-03-008The source instance is not visible in the current workspace.
ERR-03-009The source app has multiple live instances; pass --compose-hash or use a specific source UUID.
ERR-04-001Workspace credit balance is too low.
See Error Codes for the full catalog, HTTP status mappings, and the exception class behind each code.