Skip to content
ICP CLI
Feedback welcome! Report issues on GitHub, ask questions on the Forum, or chat with us on Discord.

Configuration Reference

Complete reference for icp.yaml project configuration.

For conceptual explanation, see Project Model.

File Structure

icp.yaml
canisters:
- # canister definitions or references
networks:
- # network definitions or references (optional)
environments:
- # environment definitions (optional)

Canisters

Inline Definition

canisters:
- name: my-canister
build:
steps:
- type: script
commands:
- echo "Building..."
sync:
steps:
- type: assets
dir: www
settings:
compute_allocation: 5
init_args: "()"

External Reference

canisters:
- path/to/canister.yaml
- canisters/* # Glob pattern
- services/**/*.yaml # Recursive glob

Canister Properties

PropertyTypeRequiredDescription
namestringYesUnique canister identifier
buildobjectYesBuild configuration
syncobjectNoPost-deployment sync configuration
settingsobjectNoCanister settings
init_argsstring or objectNoInitialization arguments (see Init Args)
recipeobjectNoRecipe reference (alternative to build)

Build Steps

Script Step

Execute 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"

Environment variables:

  • ICP_WASM_OUTPUT_PATH — Target path for WASM output

See Environment Variables Reference for all available variables.

Pre-built Step

Use existing WASM from a local file or remote URL:

# Local file
build:
steps:
- type: pre-built
path: dist/canister.wasm
sha256: abc123... # Optional integrity check
# Remote URL
build:
steps:
- type: pre-built
url: https://github.com/example/releases/download/v1.0/canister.wasm
sha256: abc123... # Recommended for remote files
PropertyTypeRequiredDescription
pathstringOne of path or urlLocal path to WASM file
urlstringOne of path or urlURL to download WASM file from
sha256stringNoSHA256 hash for verification (recommended for URLs)

Sync Steps

Sync steps run after canister deployment to configure the running canister.

Assets Sync

Upload files to asset canister:

# Single directory
sync:
steps:
- type: assets
dir: dist
# Multiple directories
sync:
steps:
- type: assets
dirs:
- dist
- static
- public/images
PropertyTypeRequiredDescription
dirstringOne of dir or dirsSingle directory to upload
dirsarrayOne of dir or dirsMultiple directories to upload

Script Sync

Run shell commands after deployment:

sync:
steps:
- type: script
commands:
- echo "Post-deployment setup"
- ./scripts/configure-canister.sh

Script sync steps support the same command and commands fields as build script steps.

Recipes

Recipe Reference

canisters:
- name: my-canister
recipe:
type: "@dfinity/rust@v3.0.0"
sha256: abc123... # Required for remote URLs
configuration:
package: my-crate
PropertyTypeRequiredDescription
typestringYesRecipe source (registry, URL, or local path)
sha256stringConditionalRequired for remote URLs
configurationobjectNoParameters passed to recipe template

Recipe Type Formats

# Registry (recommended)
type: "@dfinity/rust@v3.0.0"
# Local file
type: ./recipes/my-recipe.hb.yaml
# Remote URL
type: https://example.com/recipe.hb.yaml

Networks

Networks define where canisters are deployed. There are two modes:

  • Managed (mode: managed): A local test network launched and controlled by icp-cli. Can run natively or in a Docker container.
  • Connected (mode: connected): A remote network accessed by URL.

Managed Network

A managed network runs the network launcher natively on your machine. To run it in a Docker container instead, see Docker Network.

networks:
- name: local-dev
mode: managed
gateway:
bind: 127.0.0.1
port: 4943
PropertyTypeRequiredDescription
namestringYesNetwork identifier
modestringYesmanaged
gateway.bindstringNoBind address (default: 127.0.0.1)
gateway.portintegerNoPort number (default: 8000, use 0 for random)
gateway.domainsarrayNoCustom domain names the gateway responds to (e.g. my-app.localhost)
artificial-delay-msintegerNoArtificial delay for update calls (ms)
iibooleanNoInstall Internet Identity canister (default: false). Also implicitly enabled by nns, bitcoind-addr, and dogecoind-addr.
nnsbooleanNoInstall NNS and SNS canisters (default: false). Implies ii and adds an SNS subnet.
subnetsarrayNoConfigure subnet types. See Subnet Configuration.
bitcoind-addrarrayNoBitcoin P2P node addresses (e.g. 127.0.0.1:18444). Adds a bitcoin and II subnet.
dogecoind-addrarrayNoDogecoin P2P node addresses. Adds a bitcoin and II subnet.

For full details on how these settings interact, see the network launcher CLI reference.

Note: These settings apply to native managed networks only. For Docker image mode, pass equivalent flags via the args field instead.

Subnet Configuration

Configure the local network’s subnet layout:

  • Default (no subnets field): one application subnet is created.
  • With subnets: only the listed subnets are created — the default application subnet is replaced, not extended. Add application explicitly if you still need it.
  • An NNS subnet is always created regardless of configuration (required for system operations).
networks:
- name: local
mode: managed
subnets:
- application
- application
- application

Available subnet types: application, system, verified-application, bitcoin, fiduciary, nns, sns

Bitcoin and Dogecoin Integration

Connect the local network to a Bitcoin or Dogecoin node for testing chain integration:

networks:
- name: local
mode: managed
bitcoind-addr:
- "127.0.0.1:18444"

The bitcoind-addr field specifies the P2P address (not RPC) of the Bitcoin node. Multiple addresses can be specified. Dogecoin integration works the same way via dogecoind-addr. Both can be configured simultaneously.

Implicit effects: When bitcoind-addr or dogecoind-addr is configured, the network launcher automatically adds a bitcoin subnet and an II subnet (provides threshold signing keys required for chain operations). If you also explicitly specify subnets, you must include application to keep the default application subnet:

networks:
- name: local
mode: managed
bitcoind-addr:
- "127.0.0.1:18444"
subnets:
- application
- system

Connected Network

networks:
- name: testnet
mode: connected
url: https://testnet.ic0.app
root-key: <hex-encoded-key> # For non-mainnet
PropertyTypeRequiredDescription
namestringYesNetwork identifier
modestringYesconnected
urlstringYesNetwork endpoint URL
root-keystringNoHex-encoded root key (non-mainnet only)

Docker Network

A managed network can also run inside a Docker container. Adding the image field switches from native to Docker mode:

networks:
- name: docker-local
mode: managed
image: ghcr.io/dfinity/icp-cli-network-launcher
port-mapping:
- "0:4943"

To configure image-specific behavior (e.g., enabling Internet Identity, NNS, or Bitcoin integration), use the args field to pass command-line arguments to the container entrypoint:

networks:
- name: docker-local
mode: managed
image: ghcr.io/dfinity/icp-cli-network-launcher
port-mapping:
- "8000:4943"
args:
- "--ii"

The available arguments depend on the Docker image — see the image’s documentation for details.

Docker networking note: When referencing services running on the host machine from inside a container (e.g., a local Bitcoin node), use host.docker.internal instead of 127.0.0.1 or localhost. Inside a container, 127.0.0.1 refers to the container’s own loopback, not the host. For example: --bitcoind-addr=host.docker.internal:18444. Docker Desktop (macOS/Windows) resolves host.docker.internal automatically. On Linux Docker Engine, you may need to pass --add-host=host.docker.internal:host-gateway or equivalent to ensure it resolves.

See Containerized Networks for full configuration options.

Environments

environments:
- name: staging
network: ic
canisters:
- frontend
- backend
settings:
frontend:
memory_allocation: 2gib
backend:
compute_allocation: 10
environment_variables:
LOG_LEVEL: "info"
init_args:
backend: "(record { mode = \"staging\" })"
PropertyTypeRequiredDescription
namestringYesEnvironment identifier
networkstringYesNetwork to deploy to
canistersarrayNoCanisters to include (default: all)
settingsobjectNoPer-canister setting overrides
init_argsobjectNoPer-canister init arg overrides (see Init Args)

Canister Settings

See Canister Settings Reference for all options.

settings:
compute_allocation: 5
memory_allocation: 4gib
freezing_threshold: 30d
reserved_cycles_limit: 1t
wasm_memory_limit: 1gib
wasm_memory_threshold: 512mib
log_visibility: controllers
environment_variables:
KEY: "value"

Memory values accept suffixes: kb (1000), kib (1024), mb, mib, gb, gib. Cycles values accept suffixes: k (thousand), m (million), b (billion), t (trillion). Duration values accept suffixes: s (seconds), m (minutes), h (hours), d (days), w (weeks). Decimals and underscores are supported where applicable (e.g. 2.5gib, 1_000_000).

Init Args

A plain string is shorthand for inline Candid content:

init_args: "(record { owner = principal \"aaaaa-aa\" })"

File reference:

init_args:
path: ./args.bin
format: bin

Inline value (explicit):

init_args:
value: "(record { owner = principal \"aaaaa-aa\" })"
format: candid
PropertyTypeRequiredDescription
pathstringYes*Relative path to file containing init args
valuestringYes*Inline init args value
formatstringNohex, candid, or bin (default: candid)

*Exactly one of path or value must be specified.

Supported formats:

  • hex — Hex-encoded bytes (inline or file)
  • candid — Candid text format (inline or file)
  • bin — Raw binary bytes; only valid with path (e.g. output of didc encode)

Implicit Defaults

Networks

NameModeDescription
localmanagedlocalhost:8000, can be overridden
icconnectedICP mainnet, cannot be overridden

Environments

NameNetworkCanisters
locallocalAll
icicAll

Complete Example

canisters:
- name: frontend
recipe:
type: "@dfinity/asset-canister@v2.1.0"
configuration:
dir: dist
settings:
memory_allocation: 1gib
- name: backend
build:
steps:
- type: script
commands:
- cargo build --target wasm32-unknown-unknown --release
- cp target/wasm32-unknown-unknown/release/backend.wasm "$ICP_WASM_OUTPUT_PATH"
settings:
compute_allocation: 5
init_args:
value: "(record { admin = principal \"aaaaa-aa\" })"
networks:
- name: local
mode: managed
gateway:
port: 9999
environments:
- name: staging
network: ic
canisters: [frontend, backend]
settings:
backend:
compute_allocation: 10
environment_variables:
ENV: "staging"
- name: production
network: ic
canisters: [frontend, backend]
settings:
frontend:
memory_allocation: 4gib
backend:
compute_allocation: 30
freezing_threshold: 90d
environment_variables:
ENV: "production"
init_args:
backend: "(record { admin = principal \"xxxx-xxxx\" })"

Schema

JSON schemas for editor integration are available in docs/schemas/:

Configure your editor to use them for autocomplete and validation:

# yaml-language-server: $schema=https://raw.githubusercontent.com/dfinity/icp-cli/main/docs/schemas/icp-yaml-schema.json
canisters:
- name: my-canister
# ...