POST /cvms) or with PATCH /cvms/{cvm_id}, or with the matching phala deploy flags. Some of them sit behind a feature flag and are available on request: contact support to turn them on for your workspace.
Init scripts
Init scripts are small scripts Phala Cloud provides. The CVM runs them on every boot, before your containers start. You pick them by name:
The scripts always run in this order:
docker_cleanup, then env_merge.
How do I choose init scripts?
Send the full list. It replaces the scripts the CVM runs now, and[] removes them all:
PATCH /cvms/{cvm_id}. The create request still accepts the older forms init_scripts: {"env_merge": true} and enabled_init_scripts_docker_cleanup.
Storage is fixed when you create a CVM, and the default is zfs. To use docker_cleanup, create the CVM with ext4 storage.
Why does turning on docker_cleanup ask for confirmation?
Because the next boot erases your images and Docker volumes, and every boot after that does it again. On an existing CVM, the update fails withERR-03-048 unless you also send "confirm_data_wipe": true. Back up any data in Docker volumes before you turn it on.
Does each CVM have its own init scripts?
Yes. Init scripts are part of each CVM’s compose. Changing them is a compose change: the CVM gets a new compose hash and restarts, and on Onchain KMS the new hash must be registered. Redeploying an older revision brings back that revision’s init scripts. To see what a CVM runs and what you could pick, callGET /cvms/{cvm_id}/init-scripts. Each item says whether the CVM runs the script (selected), whether you can pick it (selectable) and, if not, why (reason).
Ephemeral data disk
Withrequirements.ephemeral_data_disk set to true, the CVM starts every boot with an empty data disk. The guest formats the disk before any app code runs, so nothing from earlier boots is left. Use it for workloads that must not keep data between boots.
It needs dstack OS 0.6.3 or newer.
To turn it on at create, put it in compose_file.requirements. To turn it on for an existing CVM, confirm the wipe:
confirm_data_wipe, the update fails with ERR-03-048. Turning it off needs no confirmation.
Annotations
Annotations sit behind a feature flag and are available on request. Without it, every annotations request, and a create request that carries annotations, fails with403 and ERR-03-049.
Annotations are key/value labels for tools on the host, for example a wrapper that reads the VM’s settings to place its memory or pin its vCPUs. The node keeps them with the VM.
They are host configuration, not part of your app. They never reach the CVM, are not measured and are not part of the compose hash, so attestation does not cover them. Do not rely on them for security.
How do I set annotations?
- At create: add an
annotationsmap to the create request. - On an existing CVM:
PUT /cvms/{cvm_id}/annotationswith{"annotations": {"memory_tier": "fast"}}. This replaces all annotations. To clear them, send{"annotations": {}}. - To read them:
GET /cvms/{cvm_id}/annotations. - From the CLI:
phala annotationsshows them, andphala annotations <cvm-id> memory_tier=fastsets a key and keeps the others.
ERR-03-050.
Setting annotations does not restart the CVM. Some host tools read them only when the VM starts. For those, restart the CVM after you change them.
Do annotations follow the CVM?
Phala Cloud does not keep annotations as part of the CVM’s state and never restores them. The node holds them. The audit record of a create request may include the annotations it carried.- A replica starts without annotations. Set them again on the replica.
- A CVM moved to another node keeps whatever its VM settings on the node carry.
- Other updates to the CVM never change them.
Other runners
The runner is the program that starts your app inside the CVM. The default isdocker-compose, and it is the only runner open to everyone. These two sit behind a feature flag and are available on request. Without it, a create request that picks one fails with ERR-03-045.
nerdctl-composeruns your Docker Compose YAML with nerdctl. It needs dstack OS 0.6.0 or newer. It cannot build images, so the YAML must not havebuild:sections. It is the only runner that acceptssnapshotter.bashruns the script inbash_scriptinstead of Docker Compose YAML. There are no containers, so the CVM has no container list or container logs, anddocker_cleanupis not available. If you turn onrequirements.health_check, you must also setrequirements.health_status_file. To change the script later, send{"compose": {"bash_script": "..."}}withPATCH /cvms/{cvm_id}.
compose_file.runner when you create the CVM. It cannot change afterwards.
Why does my bash CVM stay in processing?
Because your script has not exited. The CVM runsbash_script in the foreground and finishes booting only after the script returns. Until then, the CVM stays in processing with the boot step “running main script”, and it never reaches running. A script such as while true; do sleep 300; done keeps the CVM booting forever.
Start long-running work in the background and let the script return:
phala ps lists none and there are no container logs. The script’s output is in the CVM’s service journal.
Raw app-compose input
Raw app-compose input sits behind the same feature flag as the other runners. Without it, the create request fails withERR-03-045.
Instead of compose_file, a create request can send compose_file_raw: a whole app-compose JSON file as one string. Send one or the other, not both.
Phala Cloud reads the file with the same rules as compose_file and rejects fields it does not know. It then writes the compose the same way it writes any other. The bytes the CVM runs, and the compose hash, come from that output, not from the bytes you sent.
After create, the CVM is like any other. Update it with PATCH /cvms/{cvm_id}.
