mcpField
I
icp-cli

icp-cli

github.com/dfinityクラウド・DevOps39377 回インストール今日更新
リポジトリ

icp-cli について

YAML設定を使ってInternet Computerアプリを構築・デプロイするicp-cliの開発者向けスキルです。レシピ、環境、デプロイ手順に加え、設定や移行で起きやすい問題を説明します。

主な機能

  1. 01アプリのビルドとデプロイ
  2. 02YAMLによるプロジェクト設定
  3. 03レシピによるビルドテンプレートの再利用
  4. 04環境によるデプロイ先の管理
  5. 05ID、ネットワーク、canisterの管理

活用シーン

  1. 01RustまたはMotokoのcanisterをデプロイ
  2. 02デプロイ用のローカルネットワークを設定
  3. 03プロジェクトをdfxからicpへ移行

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/dfinity/icskills --skill icp-cli

インストール後、Claude Code で/icp-cliを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
binding-generation.md
bundling.md
canister-env-vars.md
dev-server.md
dfx-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 を読み込んでください。

よくある落とし穴

  1. icp の代わりに dfx を使用する。 dfx ツールは旧式です。すべてのコマンドには icp 版があります。コマンドの完全な対応表は references/dfx-migration.md を参照してください。dfx コマンドを生成したり、dfx のドキュメントを参照したりしないでください。設定には dfx.json ではなく icp.yaml を使用します。構造も異なり、キャニスターはキー付きオブジェクトではなく、オブジェクトの配列です。

  2. メインネットへのデプロイに --network ic を使用する。 icp-cli では、ネットワークを直接指定するのではなく、環境を使用します。正しいフラグは -e ic(--environment ic の短縮形)です。

    # Wrong
    icp deploy --network ic
    # Correct
    icp deploy -e ic
    

    注:-n / --network はネットワークを直接指定するもので、キャニスター ID(プリンシパル)とともに使用できます。キャニスター名を指定する場合は、-e / --environment を使用してください。トークンやサイクルの操作では、プロジェクトのキャニスターを参照しないため -n を使用してください。

  3. バージョンを固定せずにレシピを使用する。 icp-cli はバージョンが固定されていないレシピの参照を拒否します。必ずバージョンを明示してください。公式レシピは dfinity/icp-cli-recipes でホストされています。

    # Wrong — rejected by icp-cli
    recipe:
      type: "@dfinity/rust"
    
    # Correct — pinned version
    recipe:
      type: "@dfinity/[email protected]"
    
  4. レシピがあるのに手動でビルド手順を書く。 公式レシピは Rust、Motoko、アセットキャニスターのビルドに対応しています。build.steps にシェルコマンドを書く代わりに、recipe: { type: "@dfinity/[email protected]" } を使用してください。Rust レシピでは Cargo の package がデフォルトでキャニスター名に設定されるため、両者が一致する場合は設定不要です(Pitfall 21 を参照)。

  5. .icp/data/ をバージョン管理に含めない。 メインネットのキャニスター ID は .icp/data/mappings/<environment>.ids.json に保存されます。このファイルを失うと、キャニスター名とオンチェーン ID の対応関係も失われます。必ず .icp/data/ をコミットし、削除しないでください。.icp/cache/ は一時的なもので自動的に再作成されるため、.gitignore に追加してください。頻繁にリセットされる接続先ネットワークを使用する環境がある場合は、その環境に対応する特定のマッピングファイルを .gitignore に追加できます。ディレクトリ全体である .icp または .icp/data を gitignore に追加することは絶対に避けてください。

  6. 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 に変更されました。

  7. ネットワークと環境を混同する。 ネットワークは接続先のエンドポイント(URL)です。環境はネットワーク、キャニスター、設定を組み合わせたものです。デプロイ先はネットワークではなく環境(-e)です。異なる設定で複数の環境を同じネットワークに割り当てることができます(例:ステージングと本番の両方を ic に割り当てる)。

  8. 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]
    
  9. ローカルネットワークがプロジェクトごとに存在することを忘れる。 共有のグローバルネットワークを 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
    
  10. フロントエンドキャニスターのビルドコマンドを指定しない。 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
    
  11. キャニスター 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_env Cookie からこれらを読み取ります。設定から output_env_file を削除し、.env から CANISTER_ID_* を読み取るコードも削除してください。フロントエンドは ic_env Cookie を使用し、キャニスターコードは同じ変数を実行時に読み取ります(以下の「キャニスター環境変数」と「落とし穴 22」を参照)。

  12. 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 を参照してください。

  13. @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 を参照してください。

  14. 設定スタイル間でキャニスターレベルのフィールドを混在させる。 レシピを使用する場合、有効なキャニスターレベルのフィールドは 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
    
  15. 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 を参照してください。

  16. レシピでの 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.did
    

    Motoko(v5 レシピ) — mops build は .did を .mops/.build/<name>.did に自動生成します。

    • バインディング生成が不要な場合 — 作業は不要です。.mops/.build/ 内に生成された .did で十分です。コミットしないでください。
    • バインディング生成が必要な場合 — mops generate candid を使って、整理された .did を安定したパスに生成します。
      mops generate candid backend
      
      これは WASM をコンパイルせずに、Motoko ソースから Candid インターフェースを直接抽出します。mops.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 全体をビルドします。)
  17. 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"
    
  18. ローカルネットワークの起動時にポート 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: 8001
    
    icp network status --json  # ゲートウェイ URL、レプリカ URL などを返します
    
  19. CI で --silent を付けずに icp new を実行すると停止しません。 --define フラグなしで icp new を実行すると、非対話型環境では対話型プロンプトが起動し、処理が無期限に停止します。スクリプトから実行する場合は、必ず --subfolder、--define、--silent を渡してください。

    icp new my-project --subfolder rust --define project_name=my-project --silent
    
  20. メインネットで匿名アイデンティティを使用する場合。 ローカル開発では、起動時にローカルネットワークが管理対象のすべてのアイデンティティ(デフォルトの匿名アイデンティティを含む)に 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 スキルを読み込んでください。

  21. 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 が必須でした。

  22. セッターメソッドやデプロイスクリプトでカナスター 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 つのフェーズを順番に実行します。

  1. ビルド — レシピまたは明示的なビルド手順を通じて、カナスターを WASM にコンパイルします
  2. デプロイ — カナスターを作成し(新規の場合)、設定を適用して WASM をインストールします
  3. 同期 — 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 つ、常に利用できます。

環境ネットワーク用途
locallocal(管理対象、localhost:8000)ローカル開発
icic(接続済み、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
RecipeType stringRequired configOptional config
Rust@dfinity/[email protected]—package(デフォルトはcanister名)、candid、locked、shrink、compress、metadata
Motoko@dfinity/[email protected]—shrink、compress、metadata
静的サイト(フロントエンド)@dfinity/[email protected]dirbuild、presync、metadata
Asset(従来のフロントエンド)@dfinity/[email protected]dirbuild、version
Prebuilt@dfinity/[email protected]pathsha256、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 は事前に見積もりや警告を行わないため、失敗してからではなく、デプロイ前に自分で確認してください。

  1. これから作成するキャニスターの数を数えます。 icp deploy は、.icp/data/mappings/<env>.ids.json(name: id のマップ。最初のデプロイ前は存在しないため、その場合はすべてのキャニスターが対象です)に ID がない環境内のキャニスターをすべて作成します。icp deploy --no-create -e ic を実行すると、ネットワークに接続せずに一覧を確認できます。ビルド後、the following canisters do not exist: ... というエラーで停止します。
  2. 見積もります。 作成ごとに --cycles の値(デフォルトは 2T。接尾辞は k/m/b/t)に加え、サイクル台帳の手数料 100M が ID の残高から差し引かれるため、N 個のキャニスターには N × (2T + 100M) が必要です。ネットワークの作成手数料(13 ノードのサブネットで 500B)とインストール費用は、それぞれのキャニスターの 2T から支払われ、ID の残高からは差し引かれません。その後に追加でチャージできるよう、約 10% の余裕を加えてください。
  3. デプロイに使う ID の残高を icp cycles balance -n ic --identity "$ID" で比較します(落とし穴 20。-q を指定すると数値のみが出力されます)。
  4. 不足している場合は、推測せず、不足額を人に伝え、補うための方法を両方提示してください。
    • 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 が見積もりに達するまで、エージェントは待機します。
  5. 同じ 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_env Cookie をローカルでシミュレートする Vite 開発サーバーの設定。重要:getDevServerConfig() を command === "serve" ガードで囲み、vite dev の実行時のみ動作し、vite build では動作しないようにしてください。
  • references/dfx-migration.md — dfx から icp への完全な移行ガイド(コマンドの対応関係、設定の対応関係、ID/キャニスター ID の移行、フロントエンドパッケージの移行、移行後の確認チェックリスト)

コメント