| title | Build, Deploy, Sync |
|---|---|
| description | Understand the three phases that move canister source code to a running, configured state on the Internet Computer. |
Canisters go through three distinct phases when moving from source code to running on the Internet Computer.
Source Code → [Build] → WASM → [Deploy] → Running Canister → [Sync] → Configured State
Each phase has a specific purpose:
| Phase | Purpose | Commands |
|---|---|---|
| Build | Compile source to WASM | icp build or icp deploy |
| Deploy | Create canister and install WASM | icp deploy |
| Sync | Post-deployment configuration | icp deploy or icp sync |
Note: icp deploy runs all three phases in sequence. Use individual commands when you need more control.
The build phase transforms your source code into WebAssembly (WASM) bytecode.
- Build steps from your configuration execute in sequence
- Each step can run commands, copy files, or process assets
- The final output is a
.wasmfile ready for deployment
- icp-cli delegates compilation to your language toolchain (Cargo for rust, mops for Motoko, etc.)
- Build output should be reproducible — no environment specific values should be baked in.
- The toolchain decides whether rebuilding is necessary.
- As part of the build phase you might build assets to be synchronized to the canister after the WASM is installed. For example, bundled web assets to serve a frontend.
Script — Run shell commands:
build:
steps:
- type: script
commands:
- cargo build --target wasm32-unknown-unknown --release
- cp target/wasm32-unknown-unknown/release/my_canister.wasm "$ICP_WASM_OUTPUT_PATH"Pre-built — Use existing WASM:
build:
steps:
- type: pre-built
path: dist/canister.wasm
sha256: abc123... # Optional integrity checkAssets — Bundle static files:
build:
steps:
- type: script
commands:
- npm run buildScripts have access to:
ICP_WASM_OUTPUT_PATH— Where to place the final WASM
Scripts run with the canister directory as the current working directory.
See Environment Variables Reference for all available variables.
The deploy phase creates or updates canisters on a network.
When deploying a canister for the first time:
- An empty canister is created on the network
- The canister receives a unique canister ID
- Initial cycles are allocated
- Canister settings are applied (memory, compute allocation, etc.)
- Your WASM code is installed
When the canister already exists:
- The existing canister is located by ID
- The canister is stopped (waits for in-flight messages to finish)
- New WASM code is upgraded (preserving stable memory)
- The canister is started again
- Settings are updated if changed
Stopping the canister before upgrading ensures no messages are being processed during the code swap, preventing potential data inconsistencies.
The sync phase handles post-deployment operations that depend on the canister being deployed.
- Asset canisters — Upload static files after the canister is running
For frontend canisters, sync uploads your built assets:
sync:
steps:
- type: assets
dir: dist- Automatically after
icp deploy - Manually with
icp sync
Run sync without redeploying:
icp sync my-canisterThe icp deploy command is a composite command that executes multiple steps in sequence:
-
Build — Compile all target canisters to WASM (always runs)
-
Create — Create canisters on the network (only for canisters that don't exist yet)
-
Update Canister Environment Variables — For each canister being deployed:
- Collects IDs of all canisters in the environment
- Creates
PUBLIC_CANISTER_ID:<name>variables for each canister - Merges with any custom
environment_variablesfrom settings - Updates canister settings via the Management Canister
This step enables canisters to discover each other without hardcoding IDs. See Canister Discovery for details.
-
Update Settings — Apply canister settings (controllers, memory allocation, compute allocation, etc.)
-
Install — Install WASM code into canisters (always runs)
-
Sync — Run post-deployment steps like asset uploads (only if sync steps are configured)
First deployment:
- All steps run
- New canisters are created on the network
- Settings are applied
- WASM code is installed (install mode)
Subsequent deployments:
- Skip the canister creation
- Settings and Canister Environment Variables are applied if they've changed.
- Canisters are stopped, WASM code is upgraded (preserving canister state), then canisters are restarted
Unlike icp canister create (which prints "already exists" and exits), icp deploy silently skips creation for existing canisters and continues with the remaining steps.
The --mode flag controls how WASM is installed:
# Auto (default) — install for new canisters, upgrade for existing
icp deploy
# Install — only works on empty canisters
icp deploy --mode install
# Upgrade — preserves state, runs upgrade hooks
icp deploy --mode upgrade
# Reinstall — clears all state (use with caution)
icp deploy --mode reinstallWhat icp deploy does can be broken down into:
icp build # 1. Build
icp canister create # 2. Create (if needed)
# (canister env vars updated) # 3. Set environment variables
# (canister settings updated) # 4. Sync settings
icp canister install --mode auto # 5. Install
icp sync # 6. Sync (if configured)For more control, run phases individually:
# Build only — compile without deploying
icp build
# Sync only — re-upload assets without rebuilding or reinstalling
icp syncWhen to run separately:
icp build— Verify compilation succeeds before deployingicp sync— Update assets without redeploying code (faster iteration for frontends)
Note: icp deploy always builds first. There's no way to skip the build phase during deploy. The build phase relies on the underlying toolchain (Cargo, moc, etc.) handling incremental compilation.
- Local Development — Apply this in practice
- Canister Discovery — How canisters discover each other