icp-cli について
YAML設定を使ってInternet Computerアプリを構築・デプロイするicp-cliの開発者向けスキルです。レシピ、環境、デプロイ手順に加え、設定や移行で起きやすい問題を説明します。
主な機能
- 01アプリのビルドとデプロイ
- 02YAMLによるプロジェクト設定
- 03レシピによるビルドテンプレートの再利用
- 04環境によるデプロイ先の管理
- 05ID、ネットワーク、canisterの管理
活用シーン
- 01RustまたはMotokoのcanisterをデプロイ
- 02デプロイ用のローカルネットワークを設定
- 03プロジェクトをdfxからicpへ移行
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ dfinity/ icskills --skill icp-cliインストール後、Claude Code で/icp-cliを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/binding-generation.mdbundling.mdcanister-env-vars.mddev-server.mddfx-migration.md詳細
ICP CLI
概要
icp コマンドラインツールは、Internet Computer 上でアプリケーションをビルドしてデプロイします。YAML 設定、再利用可能なビルドテンプレートのレシピシステム、デプロイ先とネットワーク接続を分離する環境モデルにより、従来の dfx ツールを置き換えます。dfx は決して使用せず、常に icp を使用してください。
ここに明記されていない icp コマンドを生成する前に、icp --help または icp <subcommand> --help を実行して、そのコマンドとフラグが存在することを確認してください。dfx に相当するフラグから推測しないでください。CLI 間でフラグに互換性はありません。
インストール
npm install -g @icp-sdk/icp-cli @icp-sdk/ic-wasm
公式レシピ(@dfinity/rust、@dfinity/motoko、@dfinity/static-site、@dfinity/asset-canister)を使用する場合は、最適化とメタデータの埋め込みに必要な ic-wasm が必要です。Node.js >= 22 が必要です。Homebrew とシェルスクリプトインストーラーでも利用できます。icp-cli のリリースを参照してください。
Linux に関する注意: 最小構成でインストールした場合、システムライブラリが必要になることがあります。sudo apt-get install -y libdbus-1-3 libssl3 ca-certificates(Ubuntu/Debian)または sudo dnf install -y dbus-libs openssl ca-certificates(Fedora/RHEL)を実行してください。
前提条件
- Rust キャニスターの場合:
rustup target add wasm32-unknown-unknown - Motoko キャニスターの場合:
npm i -g ic-mopsを実行し、Motoko コンパイラーのバージョンと[canisters]エントリーを含むmops.tomlをプロジェクトのルートに配置します。[toolchain] moc = "1.9.0" [canisters.backend] main = "src/backend/main.mo"@dfinity/motoko@v5+レシピはmops build <canister-name>でコンパイルします。icp.yamlのキャニスター名は[canisters]のキーと完全に一致する必要があります。キーがない、または一致しない場合、mops buildはNo Motoko canisters found in mops.toml configurationというエラーで失敗します(Pitfall 17 を参照)。mops.tomlがない場合、mopsが見つからずレシピは失敗します。テンプレートにはmops.tomlが自動的に含まれます。手動で作成するプロジェクトでは、icp buildを実行する前に作成してください。[canisters]の設定オプション、依存関係の管理、mops buildの詳細については、mops-cliを読み込んでください。
よくある落とし穴
-
icpの代わりにdfxを使用する。dfxツールは旧式です。すべてのコマンドにはicp版があります。コマンドの完全な対応表はreferences/dfx-migration.mdを参照してください。dfxコマンドを生成したり、dfxのドキュメントを参照したりしないでください。設定にはdfx.jsonではなくicp.yamlを使用します。構造も異なり、キャニスターはキー付きオブジェクトではなく、オブジェクトの配列です。 -
メインネットへのデプロイに
--network icを使用する。 icp-cli では、ネットワークを直接指定するのではなく、環境を使用します。正しいフラグは-e ic(--environment icの短縮形)です。# Wrong icp deploy --network ic # Correct icp deploy -e ic注:
-n/--networkはネットワークを直接指定するもので、キャニスター ID(プリンシパル)とともに使用できます。キャニスター名を指定する場合は、-e/--environmentを使用してください。トークンやサイクルの操作では、プロジェクトのキャニスターを参照しないため-nを使用してください。 -
バージョンを固定せずにレシピを使用する。 icp-cli はバージョンが固定されていないレシピの参照を拒否します。必ずバージョンを明示してください。公式レシピは dfinity/icp-cli-recipes でホストされています。
# Wrong — rejected by icp-cli recipe: type: "@dfinity/rust" # Correct — pinned version recipe: type: "@dfinity/[email protected]" -
レシピがあるのに手動でビルド手順を書く。 公式レシピは Rust、Motoko、アセットキャニスターのビルドに対応しています。
build.stepsにシェルコマンドを書く代わりに、recipe: { type: "@dfinity/[email protected]" }を使用してください。Rust レシピでは Cargo のpackageがデフォルトでキャニスター名に設定されるため、両者が一致する場合は設定不要です(Pitfall 21 を参照)。 -
.icp/data/をバージョン管理に含めない。 メインネットのキャニスター ID は.icp/data/mappings/<environment>.ids.jsonに保存されます。このファイルを失うと、キャニスター名とオンチェーン ID の対応関係も失われます。必ず.icp/data/をコミットし、削除しないでください。.icp/cache/は一時的なもので自動的に再作成されるため、.gitignoreに追加してください。頻繁にリセットされる接続先ネットワークを使用する環境がある場合は、その環境に対応する特定のマッピングファイルを.gitignoreに追加できます。ディレクトリ全体である.icpまたは.icp/dataを gitignore に追加することは絶対に避けてください。 -
icp identity defaultの代わりにicp identity useを使用する。 dfx のコマンドdfx identity use <name>は、設定用のicp identity default <name>に変更されました。引数なしのicp identity defaultはゲッターで、現在のデフォルト ID を出力します。これはdfx identity whoamiと同等です。icp identity useというコマンドは存在しません。同様に、dfx identity get-principalはicp identity principalに、dfx identity removeはicp identity deleteに変更されました。 -
ネットワークと環境を混同する。 ネットワークは接続先のエンドポイント(URL)です。環境はネットワーク、キャニスター、設定を組み合わせたものです。デプロイ先はネットワークではなく環境(
-e)です。異なる設定で複数の環境を同じネットワークに割り当てることができます(例:ステージングと本番の両方をicに割り当てる)。 -
networksやenvironmentsを配列ではなく YAML マップとして記述する。icp.yamlでは、networksとenvironmentsはどちらもオブジェクトの配列であり、マップではありません。# Wrong — map syntax networks: local: mode: managed environments: staging: network: ic # Correct — array syntax networks: - name: local mode: managed environments: - name: staging network: ic canisters: [backend, frontend] -
ローカルネットワークがプロジェクトごとに存在することを忘れる。 共有のグローバルネットワークを 1 つ実行する dfx とは異なり、icp-cli はプロジェクトごとにローカルネットワークを実行します。ローカルにデプロイする前に、プロジェクトディレクトリで
icp network start -dを実行する必要があります。ローカルネットワークはシステムキャニスターとともに自動起動し、アカウントに ICP とサイクルを付与します。作業が終わったら停止してください。icp network start -d # start background network icp deploy # build + deploy + sync icp network stop # stop when done -
フロントエンドキャニスターのビルドコマンドを指定しない。 dfx はアセットキャニスターに対して
npm run buildを自動実行します。icp-cli では、レシピの設定にビルドコマンドを明示的に指定する必要があります。canisters: - name: frontend recipe: type: "@dfinity/[email protected]" # 推奨されるフロントエンドレシピ(certified-assets) configuration: dir: dist build: - npm install - npm run build -
キャニスター ID を含む
output_env_fileや.envを期待する。 dfx はoutput_env_fileを使って、キャニスター ID を.envファイル(CANISTER_ID_BACKEND=...)に書き込みます。icp-cli は.envファイルを生成しません。代わりに、icp deploy中にキャニスター ID を環境変数(PUBLIC_CANISTER_ID:<name>)としてキャニスターに直接注入します。フロントエンドはフロントエンドキャニスター(static-site または従来のアセットキャニスター)が設定するic_envCookie からこれらを読み取ります。設定からoutput_env_fileを削除し、.envからCANISTER_ID_*を読み取るコードも削除してください。フロントエンドはic_envCookie を使用し、キャニスターコードは同じ変数を実行時に読み取ります(以下の「キャニスター環境変数」と「落とし穴 22」を参照)。 -
TypeScript バインディングの生成に
dfx generateを期待する。 icp-cli にはdfx generateに相当する機能はありません。ビルド時に.didファイルから TypeScript バインディングを生成するには、@icp-sdk/bindgen(>= 0.4.0)を使用し、@icp-sdk/coreは^6に固定してください(SDK の他のピア依存関係も^6のため、異なるメジャーバージョンではERESOLVEによりインストールに失敗します)。インポートをすっきりさせるにはoutDir: "./src/bindings"を使用します(例:./bindings/backend)。.didファイルはディスク上に存在している必要があります。リポジトリにコミットするか、先にicp buildで生成してください(candidが指定されていない場合、レシピが自動生成します)。Vite プラグインの設定全体についてはreferences/binding-generation.mdを参照してください。 -
@dfinity/agentのアクター設定を@icp-sdk/bindgenに移植する。 以前の@dfinity/agentのパターンは、new HttpAgent({ identity, host })とともに使用するcreateActor(canisterId, { agent })でした。@icp-sdk/bindgenのパターンはcreateActor(canisterId, { agentOptions: { identity, rootKey } })です。バインディングが内部でエージェントを作成するため、ブラウザーのコードではhostを設定しません。事前に作成した{ agent }も引き続き動作しますが、new HttpAgent()は非推奨です。正しいパターンとhostを設定する必要がある場合についてはreferences/binding-generation.mdを参照してください。 -
設定スタイル間でキャニスターレベルのフィールドを混在させる。 レシピを使用する場合、有効なキャニスターレベルのフィールドは
name、recipe、sync、settings、init_argsのみです。candid、build、wasmなどのフィールドは、レシピと併用するキャニスターレベルのフィールドとしては無効です。レシピ固有のオプションはrecipe.configuration内に指定します。buildのみを使用する場合(レシピなし)、有効なキャニスターレベルのフィールドはname、build、sync、settings、init_argsです。init_arg_fileというフィールドは存在しません。代わりにinit_args.pathを使用してください(例:init_args: { path: ./args.bin, format: bin })。正確なフィールドのリファレンスについては、icp-cli configuration referenceを参照してください。# 誤り — レシピを使用する場合、candid はキャニスターレベルのフィールドではありません canisters: - name: backend candid: backend/backend.did recipe: type: "@dfinity/[email protected]" # 正しい — candid は recipe.configuration 内に指定します canisters: - name: backend recipe: type: "@dfinity/[email protected]" configuration: candid: backend/backend.did -
mopsが見つけられない場所にmops.tomlを配置する。mopsはビルドの作業ディレクトリから上位ディレクトリを検索します。mops.tomlの配置場所は、キャニスターの定義方法によって異なります。- インラインキャニスター(
icp.yaml内に直接定義):ビルドの作業ディレクトリはプロジェクトのルートです。mops.tomlはicp.yamlと同じプロジェクトルートに配置してください。src/backend/内にあるmops.tomlは見つかりません。 - パスベースのキャニスター(
canisters/*または./my-canisterを介して参照し、それぞれに独自のcanister.yamlがあるもの):ビルドの作業ディレクトリはキャニスターディレクトリです。キャニスターごとの依存関係とコンパイラバージョンを設定するには、各キャニスターのディレクトリにmops.tomlを配置してください。または、親ディレクトリにある共有のmops.tomlにフォールバックさせるため、省略することもできます。
mops.tomlが見つからない場合、プロジェクト設定を特定できないためmops buildは失敗します。mops.tomlが存在していても、対応する[canisters.<name>]エントリーがない場合は、Pitfall 17 を参照してください。 - インラインキャニスター(
-
レシピでの Candid ファイル生成について誤解する。 バインディング生成ツール(例:
@icp-sdk/bindgen)では、既知のパスに.didファイルが必要です。設定方法はレシピによって異なります。Rust —
icp.yamlのrecipe.configuration内にcandidを指定します。- 指定する場合:ファイルがあらかじめ存在している必要があります。レシピはそのファイルをそのまま使用し、新たに生成しません。
- 省略する場合:レシピは
candid-extractorを使って.didをビルドキャッシュ内に自動生成します(プロジェクト内の予測可能なパスには生成されません)。
生成してコミットするには、次のコマンドを実行してから、
recipe.configuration内にcandid: backend/backend.didを追加します。cargo install candid-extractor # 初回セットアップ時のみ icp build backend candid-extractor target/wasm32-unknown-unknown/release/backend.wasm > backend/backend.didMotoko(v5 レシピ) —
mops buildは.didを.mops/.build/<name>.didに自動生成します。- バインディング生成が不要な場合 — 作業は不要です。
.mops/.build/内に生成された.didで十分です。コミットしないでください。 - バインディング生成が必要な場合 —
mops generate candidを使って、整理された.didを安定したパスに生成します。
これは WASM をコンパイルせずに、Motoko ソースから Candid インターフェースを直接抽出します。mops generate candid backendmops.tomlで[canisters.backend].candidが設定されている場合は、そのファイルを上書きします。設定されていない場合は、mainの隣に<name>.didを書き込み(例:main = "src/backend/main.mo"→src/backend/backend.did)、そのパスをmops.tomlに記録します。バインディングツールの設定(例:@icp-sdk/bindgenのdidFile)で、その.didを指定してください。インターフェースを変更するたびに再実行し、.didとmops.tomlを一緒にコミットしてください。詳細についてはmops-cliを読み込んでください。(以前のmops build backendとcp .mops/.build/backend.did …の2段階の手順も引き続き使用できますが、インターフェースの抽出だけを目的として WASM 全体をビルドします。)
-
mops.tomlに[canisters]キーがない、または一致していない場合。@dfinity/motoko@v5+のレシピでは、icp.yamlのnameフィールドから取得した名前を使ってmops build <canister-name>を呼び出します。mops buildを実行するには、mops.tomlに対応する[canisters.<name>]エントリが必要です。エントリがない場合、またはキーが完全に一致しない場合(大文字・小文字も区別されます)、ビルドは次のエラーで失敗します。No Motoko canisters found in mops.toml configuration対応するエントリを追加します。キーは
icp.yamlのname:の値と一致させる必要があります。[canisters.backend] main = "src/backend/main.mo" -
ローカルネットワークの起動時にポート 8000 がすでに使用されている場合。 次の 2 つのケースがあります。
ケース A — 別の icp-cli プロジェクトがポートを使用している場合。
--project-root-override(すべてのコマンドで使用できるグローバルフラグ)を使って、そのプロジェクトのネットワークを停止します。icp network stop --project-root-override /path/to/other-project停止せずに両方のネットワークを同時に実行するには(並列の git worktree など)、
gateway.port: 0を設定すると、それぞれに空きポートが割り当てられます。詳細は「仕組み」の「並列エージェントと worktree」を参照してください。ケース B — icp 以外のサービスがポートを使用している場合。
icp.yamlで別のポートを設定し、localhost:8000 をハードコードする代わりにicp network status --jsonで実際の URL を動的に取得します。networks: - name: local mode: managed gateway: port: 8001icp network status --json # ゲートウェイ URL、レプリカ URL などを返します -
CI で
--silentを付けずにicp newを実行すると停止しません。--defineフラグなしでicp newを実行すると、非対話型環境では対話型プロンプトが起動し、処理が無期限に停止します。スクリプトから実行する場合は、必ず--subfolder、--define、--silentを渡してください。icp new my-project --subfolder rust --define project_name=my-project --silent -
メインネットで匿名アイデンティティを使用する場合。 ローカル開発では、起動時にローカルネットワークが管理対象のすべてのアイデンティティ(デフォルトの匿名アイデンティティを含む)に ICP とサイクルを付与するため、アイデンティティやサイクルの設定をしなくてもすぐに開発を始められます。メインネットではこの仕組みは適用されず、匿名アイデンティティは決して使用しないでください。誰でも共有しているため、そこに送金した ICP は誰でも利用でき、そのアイデンティティでデプロイしたキャニスターは制御できません。
メインネットにデプロイする前に、名前付きアイデンティティに切り替えます。
icp identity list # 使用可能なアイデンティティを確認します(`identities` ではなく `identity` を使います) icp identity default my-identity # 既存のアイデンティティに切り替えます # or: icp identity new my-identity && icp identity default my-identity次に、残高があることを確認します。新しいアイデンティティの場合は、続行する前に ICP またはサイクルを入金する必要があります。
icp token balance -n ic # メインネットの ICP 残高を確認します icp cycles balance -n ic # メインネットのサイクル残高を確認します icp identity account-id # 必要に応じて入金に使うアカウント ID を取得しますカードがあり ICP を持っていない場合、
icp cycles buy --amount <usd> -n ic(またはデプロイに必要な量を指定する--cycles <n>。見積もりについては、後述の「メインネット向けのアイデンティティへの入金」を参照)を実行すると、CyclePay のオンチェーンゲートウェイを通じてアイデンティティ自体にサイクルを購入できます。エージェントが注文を作成し、人間が表示されたリンクから支払うと、サイクルがアイデンティティの cycles-ledger アカウントに入金され、icp deploy -e icでその残高が使用されます。このフロー、エージェント用フラグ(--yes --no-open --json)、注文の状態については、buy-cyclesスキルを読み込んでください。 -
Rust のレシピで
packageを過剰に指定する(または誤って省略する)。@dfinity/[email protected]以降、package設定は任意で、デフォルトではicp.yamlのカナスターnameが使われます。慣例として、カナスターのnameをCargo.tomlの[package] nameと一致させ、packageは省略してください。# 推奨 — name が Cargo パッケージと一致するため、package 設定は不要 canisters: - name: backend # Cargo.toml の [package] name = "backend" と一致 recipe: type: "@dfinity/[email protected]" # 名前が異なる場合(例:ワークスペースクレート)にのみ必要 canisters: - name: backend recipe: type: "@dfinity/[email protected]" configuration: package: my-project-backend # Cargo.toml の実際の [package] name名前が異なる場合に
packageを省略すると、パッケージが見つからないというエラーでcargo buildが失敗します。正確な[package] nameを設定してください。v3.3.0より前のレシピバージョンでは、すべての場合にpackageが必須でした。 -
セッターメソッドやデプロイスクリプトでカナスター ID を手動で配線する。 デプロイ後のスクリプトから呼び出すコントローラー専用のセッター(
setBridge(principal))や、settings.environment_variablesまたは init 引数に兄弟カナスターの ID をハードコードする必要はありません。icp deployは、すべてのカナスターの ID をPUBLIC_CANISTER_ID:<canister-name>として各カナスターの設定に注入します。カナスターコードは実行時に、環境ごとの正しい値を読み取れます(Canister Environment Variables を参照)。セッターを使った配線はより脆弱です。--mode reinstallを実行すると保存されたポインターがひそかに消去されますが、自動変数はデプロイのたびに再設定されます。
仕組み
プロジェクトの作成
icp new はテンプレートからプロジェクトを生成します。対話なしで使用するには、--subfolder、--define、--silent を渡します。
icp new my-project --subfolder rust --define project_name=my-project --silent
利用可能なテンプレートとオプションについては、dfinity/icp-cli-templates を参照してください。
ビルド → デプロイ → 同期
Source Code → [Build] → WASM → [Deploy] → Running Canister → [Sync] → Configured State
icp deploy は次の 3 つのフェーズを順番に実行します。
- ビルド — レシピまたは明示的なビルド手順を通じて、カナスターを WASM にコンパイルします
- デプロイ — カナスターを作成し(新規の場合)、設定を適用して WASM をインストールします
- 同期 —
scriptまたはpluginの手順を通じてデプロイ後の操作を実行します(例:アセットのアップロード)。アセットのアップロードは CLI に組み込まれていません。フロントエンドレシピは、dirの内容をアップロードするplugin同期手順を提供します。推奨は@dfinity/[email protected](認証済みアセット)で、従来版は@dfinity/[email protected]です。従来の組み込みtype: assets手順は icp-cli 0.3.0 で削除されました。static-siteスキルを参照してください。
フェーズを個別に実行すると、より細かく制御できます。
icp build # Build only
icp deploy # Full pipeline (build + deploy + sync)
icp sync my-canister # Sync only (e.g., re-upload assets)
環境とネットワーク
暗黙的な環境が 2 つ、常に利用できます。
| 環境 | ネットワーク | 用途 |
|---|---|---|
local | local(管理対象、localhost:8000) | ローカル開発 |
ic | ic(接続済み、https://icp-api.io) | メインネットの本番環境 |
ic ネットワークは保護されており、上書きできません。
カスタム環境を使うと、同じネットワーク上に複数のデプロイ先を設定できます。
environments:
- name: staging
network: ic
canisters: [frontend, backend]
settings:
backend:
compute_allocation: 5
- name: production
network: ic
canisters: [frontend, backend]
settings:
backend:
compute_allocation: 20
freezing_threshold: 7776000
並列エージェントとワークツリー
ゲートウェイポートの分離
ローカルネットワークはプロジェクトごとに分離され、プロジェクトルートをキーとして管理されます(Pitfall 9)。同じリポジトリの別々の Git ワークツリーは、それぞれ異なるプロジェクトルートとなるため、各ワークツリーで独立したローカルネットワークを実行できます。これにより、複数のエージェントやブランチが互いに干渉せず、並行してビルドやデプロイを行えます。唯一の障害となるのがゲートウェイポートです。すべてのワークツリーでデフォルトのポートは 8000 のため、2 回目の icp network start はポート競合で失敗します。
管理対象ネットワークのゲートウェイポートを 0 に設定すると、OS がワークツリーごとに空いているエフェメラルポートを割り当てます。
networks:
- name: local
mode: managed
gateway:
port: 0 # 0 = OS picks a free port — avoids collisions across worktrees
icp network start -d は選択されたポートを出力します(Network started on port 58157)。テスト、スクリプト、別のエージェントから利用するために、後からポートを確認するには、実行中のネットワークを照会して gateway_url を読み取ります。
icp network start -d
icp network status --json
# -> { "managed": true, "api_url": "http://localhost:58157/", "gateway_url": "http://localhost:58157/", ... }
icp network status --json | jq -r '.gateway_url' # http://localhost:58157/
port: 0 を使うときは、localhost:8000 をハードコードしないでください。ポートは起動のたびに変わるため、毎回 icp network status --json から gateway_url(または api_url)を読み取ってください。ディレクトリの外から特定のワークツリーのネットワークを指定するには、グローバルな --project-root-override <path> フラグを渡します(例:icp network status --json --project-root-override /path/to/worktree)。
グローバル CLI 状態の分離(ICP_HOME)
プロジェクトローカルネットワークが分離するのは、プロジェクトごとの状態だけです。ID、設定、ダウンロード済みパッケージのキャッシュはグローバルで、OS ユーザーごとに 1 つのディレクトリに保存されます。場所は ~/.local/share/icp-cli/(Linux)、~/Library/Application Support/org.dfinity.icp-cli/(macOS)、または %APPDATA%\icp-cli\data\(Windows)です。この中の identity/、settings/、pkg/ はそれぞれブロッキング型のアドバイザリロック(.lock)で保護されるため、同じものにアクセスする複数の icp 呼び出しは直列化されます。ロックを待つことになり、失敗はしません。複数のエージェントが同時にビルドすると、レシピやネットワークランチャーのダウンロード中にパッケージキャッシュのロックを取り合います。
ICP_HOME はそのディレクトリを上書きし、各エージェントに独自のコピーを割り当てます。
export ICP_HOME=/path/to/worktree/.icp-home
icp identity new dev --storage plaintext
icp deploy
注意点を、問題が発生する順に示します。
- OS のキーリングは共有されたままです。 キーリングのエントリーは、サービス
icp-cliと ID 名の組み合わせで識別されます。ICP_HOMEはキーに含まれません。それぞれ分離されたホームでicp identity new devを実行すると(デフォルトの保存先はキーリングです)、同じエントリーに書き込まれ、互いの内容が上書きされます。キーを$ICP_HOME/identity/keys/<name>.pemに保存し、確実に分離するには--storage plaintextを渡してください。同じことはicp identity importとicp identity link webにも当てはまります。これらのセッションキーも、デフォルトではキーリングに保存されます。プレーンテキストキーを使うのは、使い捨てのローカル ID と CI 用 ID に限ってください。メインネットのカニスターを制御する ID や、価値を保持する ID には決して使わないでください(Pitfall 20)。 - 新しいホームは空です。 ID、設定、キャッシュはありません。デフォルト ID は anonymous です。管理対象のローカルネットワークでは自動的に初期設定されますが、メインネットでは使用できません。
- パッケージキャッシュはホームごとに再ダウンロードされます。
pkg/にはネットワークランチャーとすべてのレシピが格納され、容量は数百 MB に達します。新しいホームには、既存のpkg/をコピーして内容を用意するか、すべてのホームで共通のランチャーバイナリをICP_CLI_NETWORK_LAUNCHER_PATH=/path/to/icp-cli-network-launcherで指定してください。 - そのエージェントのセッションでは、すべての
icp呼び出しでICP_HOMEを設定する必要があります。 最初の呼び出しだけでは不十分です。設定を忘れたコマンドは、暗黙のうちに共有されるデフォルトのホームと別のデフォルト ID にフォールバックします。
エージェント間で実際に競合が発生する場合にのみ、これを利用してください。同じ ID セットを共有し、キャッシュへのアクセスが直列化されても問題ない別々のワークツリーでは、設定する必要はありません。
インストールモード
icp deploy # Auto: install new, upgrade existing (default)
icp deploy --mode upgrade # Preserve state, run upgrade hooks
icp deploy --mode reinstall # Clear all state (dangerous)
プロジェクトを.icpパッケージにバンドルする(実験的機能)
icp project bundleは、プロジェクトを自己完結型のデプロイ可能なアーカイブにパッケージ化します(icp-cli >= 0.3.0)。これは実験的な機能であり、意図的にヘルプ出力から隠されています — icp --helpとicp project --helpには表示されませんが、コマンドは存在し、動作します。ヘルプに記載がないからといって存在しないと判断したり、自発的に提案したりしないでください — アプリのバンドルまたは.icpパッケージの作成をユーザーが明示的に求めた場合にのみ使用してください。
icp project bundle --output my-app.icp # gzipped tar; --output accepts any path
バンドルからのデプロイ方法、アーカイブの内容、バンドルが失敗する条件、パッケージをCaffeineクラウドエンジンにアップロードする方法については、references/bundling.mdを参照してください。
設定
Rust canister
canisters:
- name: backend
recipe:
type: "@dfinity/[email protected]"
configuration:
candid: backend.did # optional — if specified, file must exist (auto-generated when omitted)
# package: my-crate # optional — only when the Cargo [package] name differs from the canister name
慣例として、canisterのnameはCargo.tomlの[package] nameと一致させる必要があります。一致する場合、packageは省略できます(recipe >= v3.3.0では、デフォルトでcanister名が設定されます)。packageを明示的に設定するのは、Cargoパッケージ名が異なる場合に限ってください — たとえば、異なる名前のcrateを含むワークスペースの場合です(Pitfall 21を参照)。
Motoko canister
v5 recipeはコンパイルをmops buildに委任します。canisterの設定(main、candid、args)はicp.yamlからmops.tomlに移動します。
# icp.yaml
canisters:
- name: backend
recipe:
type: "@dfinity/[email protected]"
# mops.toml
[toolchain]
moc = "1.9.0"
[canisters.backend]
main = "src/backend/main.mo"
candid = "backend.did" # optional — auto-generated to .mops/.build/ when omitted
canister名(backend)は、icp.yamlとmops.tomlで完全に一致させる必要があります。icp.yamlにrecipe.configurationブロックは必要ありません。
静的サイト(フロントエンド)
canisters:
- name: frontend
recipe:
type: "@dfinity/[email protected]"
configuration:
dir: dist
build:
- npm install
- npm run build
@dfinity/static-site(certified-assets canister)が、推奨されるフロントエンドrecipeです。従来の@dfinity/[email protected] recipeも既存プロジェクトでは引き続きサポートされています — 両方のrecipeと移行方法については、static-siteスキルを参照してください。
複数のcanisterを含むプロジェクトでは、すべてのcanisterを同じcanisters配列に記載してください。icp-cliはそれらを並列にビルドします。dependenciesフィールドはありません — canister間の通信にはCanister Environment Variablesを使用してください。
カスタムビルド手順(recipeなし)
recipeを使用しない場合、canisterレベルで有効なフィールドはname、build、sync、settings、init_argsのみです。wasm、candid、metadataフィールドはありません — 代わりに、これらはビルドスクリプト内で処理してください。
- WASM出力:最終的なWASMを
$ICP_WASM_OUTPUT_PATHにコピーします - Candidメタデータ:
ic-wasmを使用してcandid:serviceメタデータを埋め込みます - Candidファイル:
.didファイルはic-wasmコマンドでのみ参照され、YAMLフィールドとしては指定しません
canisters:
- 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"
- ic-wasm "$ICP_WASM_OUTPUT_PATH" -o "$ICP_WASM_OUTPUT_PATH" metadata candid:service -f backend/backend.did -v public --keep-name-section
利用可能なrecipe
| Recipe | Type string | Required config | Optional config |
|---|---|---|---|
| Rust | @dfinity/[email protected] | — | package(デフォルトはcanister名)、candid、locked、shrink、compress、metadata |
| Motoko | @dfinity/[email protected] | — | shrink、compress、metadata |
| 静的サイト(フロントエンド) | @dfinity/[email protected] | dir | build、presync、metadata |
| Asset(従来のフロントエンド) | @dfinity/[email protected] | dir | build、version |
| Prebuilt | @dfinity/[email protected] | path | sha256、shrink、compress、metadata |
フロントエンドのホスティングには、@dfinity/static-siteの使用を推奨します。@dfinity/asset-canisterは従来のasset canisterです(static-siteスキルを参照)。
最新のrecipeバージョンは、dfinity/icp-cli-recipesのリリースで確認してください。recipeの展開後の有効な設定を確認するには、icp project showを使用してください。
Canister 環境変数
icp deploy の実行時に、icp-cli は環境内のすべての canisterの ID(テキスト形式の principal)を、PUBLIC_CANISTER_ID:<canister-name> としてすべての canister の設定に注入します。これらは canister の設定環境変数であり、実行時に canister のコードから読み取れます。環境ごとの値はデプロイのたびに更新されるため、設定を一切変更せずに、ローカル、ステージング、メインネットで同じコードを使用できます。
**canister 間の接続には、**セッターメソッド、初期化引数、デプロイ後のスクリプト(落とし穴 22)ではなく、これらを使用してください。呼び出し時に遅延して読み取ります。Motoko:Runtime.envVar<system>(...)(motoko-core v2.1.0 以降)、Rust:ic_cdk::api::env_var_value(...)。コードと初回インストール/再インストール時の動作については、references/canister-env-vars.md を参照してください。
フロントエンド(JavaScript):フロントエンド canister(静的サイトまたは従来のアセット canister)は、すべての HTML レスポンスに設定される ic_env Cookie を通じて変数を公開します。@icp-sdk/core を使って読み取ります:
import { safeGetCanisterEnv } from "@icp-sdk/core/agent/canister-env";
const backendId = safeGetCanisterEnv()?.["PUBLIC_CANISTER_ID:backend"];
注意事項:
- 変数はデプロイ時にのみ更新されます。canister を追加した後は、すべての canister に完全な ID 一覧が設定されるよう、canister 名を指定せずに
icp deployを実行してください。 - ユーザー定義変数(
icp.yamlのsettings.environment_variables)は、環境間で共有される静的な YAML 文字列です。create-class インストール(初回インストールまたは--mode reinstall)ではこれらが再適用され、icp canister settings update --add-environment-variableで設定した値が上書きされます。このようなデプロイの後は、環境固有の値(本番環境のオリジンなど)を再設定してください。 - レプリカでは、環境変数の値は最大 128 文字に制限されます。
詳細なリファレンス:icp-cli 環境変数。
Web ID フロー
icp identity link web を扱う専用スキルが 2 つあります。タスクに合ったものを読み込んでください。どちらにも、標準入力の「Enter キーを押してください」という待機、ブラウザーでのサインイン手順、各フラグ固有の注意事項が記載されています。
deploy-to-cloud-engine—--auth <console-origin>を使って CLI をクラウドエンジンのコンソールにリンクし、エンジンのサブネットにデプロイしますagent-web-identity—--app <domain>を使ってアプリ固有の principal の委任を取得し、ユーザーとして canister を呼び出します
メインネット用の ID への資金追加
新しい ID には ICP もサイクルもありません。icp deploy -e ic を実行すると、Insufficient cycles. Requested: <n> cycles, available balance: 0 cycles.(またはサイクル台帳からの insufficient liquid cycles balance)というエラーで失敗します。これは、デプロイに使う ID のメインネット上のサイクル台帳残高が空であることを意味します。CLI は事前に見積もりや警告を行わないため、失敗してからではなく、デプロイ前に自分で確認してください。
- これから作成するキャニスターの数を数えます。
icp deployは、.icp/data/mappings/<env>.ids.json(name: idのマップ。最初のデプロイ前は存在しないため、その場合はすべてのキャニスターが対象です)に ID がない環境内のキャニスターをすべて作成します。icp deploy --no-create -e icを実行すると、ネットワークに接続せずに一覧を確認できます。ビルド後、the following canisters do not exist: ...というエラーで停止します。 - 見積もります。 作成ごとに
--cyclesの値(デフォルトは 2T。接尾辞はk/m/b/t)に加え、サイクル台帳の手数料 100M が ID の残高から差し引かれるため、N 個のキャニスターにはN × (2T + 100M)が必要です。ネットワークの作成手数料(13 ノードのサブネットで 500B)とインストール費用は、それぞれのキャニスターの 2T から支払われ、ID の残高からは差し引かれません。その後に追加でチャージできるよう、約 10% の余裕を加えてください。 - デプロイに使う ID の残高を
icp cycles balance -n ic --identity "$ID"で比較します(落とし穴 20。-qを指定すると数値のみが出力されます)。 - 不足している場合は、推測せず、不足額を人に伝え、補うための方法を両方提示してください。
- ICP がある場合(
icp token balance -n icで十分な残高が表示される場合):icp cycles mint --cycles <gap> -n icで必要な分だけ変換します(cycles-managementを参照)。 - ICP がなく、カードを使う場合:
icp cycles buy --cycles <gap> -n ic --identity "$ID" --no-open --yes --jsonで不足分を購入するのに必要な最小額を支払います。購入フロー、リンクの引き継ぎ、注文の状態については、buy-cyclesスキルを読み込みます。支払うのは人です。icp cycles balance -n icが見積もりに達するまで、エージェントは待機します。
- ICP がある場合(
- 同じ ID を使ってデプロイします:
icp deploy -e ic --identity "$ID"。
参考資料
CLI と設定スキーマの全容については、icp-cli ドキュメントインデックスを参照してください。
特定のトピックについて詳しく知りたい場合は、必要に応じて以下の参考ファイルを参照してください。
references/binding-generation.md—@icp-sdk/bindgenによる TypeScript バインディングの生成(Vite プラグイン、CLI、アクターのセットアップ)references/bundling.md—icp project bundleの詳細:アーカイブの内容、バンドルが失敗する 4 つの条件、.icpパッケージを Caffeine クラウドエンジンにアップロードする方法references/canister-env-vars.md— 実行時にキャニスターコードからPUBLIC_CANISTER_ID:<name>を読み取る方法(Motoko/Rust の例、遅延読み取りパターン)references/dev-server.md—ic_envCookie をローカルでシミュレートする Vite 開発サーバーの設定。重要:getDevServerConfig()をcommand === "serve"ガードで囲み、vite devの実行時のみ動作し、vite buildでは動作しないようにしてください。references/dfx-migration.md— dfx から icp への完全な移行ガイド(コマンドの対応関係、設定の対応関係、ID/キャニスター ID の移行、フロントエンドパッケージの移行、移行後の確認チェックリスト)