Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
dfinity avatar

Deploy To Cloud Engine

  • 70 installs
  • 28 repo stars
  • Updated August 4, 2026
  • dfinity/icskills

Deploy a built IC project to a user's own cloud engine by linking the console identity and running a subnet-targeted icp deploy.

About

Deploys an already-built Internet Computer project onto a user's own cloud engine (OpenCloud/control-panel) by linking the CLI identity, targeting the engine subnet, and tagging canisters for the console. A developer uses it to ship an app to their cloud engine from a coding agent.

  • Links the icp CLI to the engine console identity via `icp identity link web`
  • Runs a subnet-targeted `icp deploy` and tags canisters with __META_ vars

Deploy To Cloud Engine by the numbers

  • 70 all-time installs (skills.sh)
  • Ranked #617 of 1,435 DevOps & CI/CD skills by installs in the Skillselion catalog
  • Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/dfinity/icskills --skill deploy-to-cloud-engine

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs70
repo stars28
Last updatedAugust 4, 2026
Repositorydfinity/icskills

What it does

Deploy a built IC project to a user's own cloud engine by linking the console identity and running a subnet-targeted icp deploy.

Files

SKILL.mdMarkdownGitHub ↗

Deploy to Cloud Engine

What This Is

A cloud engine is a user-owned slice of Internet Computer capacity, administered from a web console (by default https://opencloud.org). Each engine runs on a single subnet. This skill takes a project that already builds and gets it deployed onto that engine, from a coding agent.

This skill only covers the cloud-engine-specific steps: linking the CLI to the engine's console identity, and a subnet-targeted deploy. For everything else about the CLI (icp.yaml, recipes, environments, bindings, identities), load the `icp-cli` skill.

Before running any icp command you are unsure of, run icp <subcommand> --help (e.g. icp identity link --help, icp deploy --help) to confirm the command and flags exist. Do not infer flags. Authoritative reference: https://cli.internetcomputer.org/llms.txt

What You Need

Two values. Look for them first in icp.yaml or earlier in the conversation. One has a default; the other you must ask for:

1. Console origin — the URL the user signs in to their cloud engine console with. Defaults to `https://opencloud.org` (the main OpenCloud console). It is used as the --auth origin in Step 1 so the linked CLI identity derives the same principal that administers the engine. Use the default, but say so and give the user a chance to override before linking:

  • Say: "I'll link the CLI against https://opencloud.org, the default console. If you sign in to your engine console at a different URL, tell me now."
  • Only use a different origin when the user names one — never substitute another URL on your own; the --auth origin determines the derived principal (see Pitfall 2).

2. Subnet id — the subnet the engine deploys to, required by icp deploy --subnet. There is no default; never guess it. The user finds it on the engine's App Center / Applications page in the console. If absent, ask and do not proceed without it:

  • Ask: "What is your engine's subnet id? It is shown on your engine's App Center / Applications page."

Record both so you do not re-ask within the session.

Prerequisites

  • icp on $PATH — see the `icp-cli` skill to install. Verify with icp --version (this skill's commands are verified against 0.3.0).
  • A project that already builds. If it does not build or package yet, set that up first (see the icp-cli skill), then return here.

Step 1 — Link the CLI to your engine identity (once per machine)

The CLI must sign as the same identity that administers the engine — that is the principal you log in to the console with.

First check what already exists:

icp identity list      # names + principals; * marks the active identity

The list does not show which console (if any) an identity was linked against — that cannot be determined from the CLI. Decide like this:

  • Only `anonymous` (or plain local identities) listed — no web-linked identity exists; run the link command below.
  • An identity the user recognizes as their engine identity (by name or principal) — set it active (below) and skip to Step 2.
  • Unsure — ask the user, or simply relink under a new name; linking again is cheap and safe.

To link, run this, substituting a name the user picks — <your-identity-name> is any local label, not a fixed value (do not hardcode something like my-engine-admin); reuse the same name in every command below:

icp identity link web <your-identity-name> --auth <console-origin>
  • Use https://opencloud.org as <console-origin> unless the user named a different console. Never omit --auth: the flag has a built-in default (https://id.ai) that is not your console and silently derives the wrong principal.
  • The command first waits at a "Press Enter to log in" prompt before anything happens. Run it interactively when you can; in a non-interactive shell (e.g. a background process) pipe a real newline:
  printf '\n' | icp identity link web <your-identity-name> --auth <console-origin>

Do not redirect stdin from /dev/null — the bare EOF does not satisfy the prompt, and the command sits on "Press Enter to log in" indefinitely with no browser ever opening.

  • After Enter it opens a browser tab. The user completes the Internet Identity sign-in there. Wait for them to confirm before continuing — you cannot complete the sign-in for them.
  • --auth must be the exact console origin (scheme + host), e.g. https://opencloud.org. A mismatched origin derives a different principal, and the engine will reject the deploy as unauthorized.
  • This is a one-time, per-machine step.

Then make it the active identity and verify:

icp identity default <your-identity-name>
icp identity default     # prints the active identity name
icp identity principal   # prints the principal the deploy will sign as

Step 2 — Name the app in the console (recommended)

By default, CLI-deployed canisters appear on the engine console's Applications page as bare rows labelled only by their principal id. Three canister environment variables make the console group them into a single named application with readable per-canister labels and an "Open" button. Set them once in your project config:

  • __META_PROJECT — the application name. Canisters that share the same value are grouped into one named app, so set an identical value on every canister of the app.
  • __META_NAME — the per-canister display label (e.g. Backend, Frontend).
  • __META_MAIN_CANISTER — the literal string "true" on the single entry-point canister (usually the frontend/asset canister). That canister gets the "Open" button and the app's public URL.

Set them under each canister's settings.environment_variables — this is valid alongside a recipe. With per-canister canister.yaml files:

# frontend/canister.yaml
name: frontend
recipe:
  type: "@dfinity/asset-canister@v2.2.1"
  configuration:
    build:
      - npm install
      - npm run build
    dir: dist
settings:
  environment_variables:
    __META_PROJECT: "My App"
    __META_NAME: "Frontend"
    __META_MAIN_CANISTER: "true"
# backend/canister.yaml
name: backend
recipe:
  type: "@dfinity/motoko@v4.1.0"
  configuration:
    main: src/main.mo
settings:
  environment_variables:
    __META_PROJECT: "My App"
    __META_NAME: "Backend"

For a single inline icp.yaml (canisters defined there directly), put the same settings.environment_variables block under each canister entry. Note the inline form: canisters is an array of {name, recipe, settings} items, not a map keyed by canister name:

# icp.yaml — canisters defined inline
canisters:
  - name: frontend
    recipe: # … as in the canister.yaml example above
    settings:
      environment_variables:
        __META_PROJECT: "My App"
        __META_NAME: "Frontend"
        __META_MAIN_CANISTER: "true"
  - name: backend
    recipe: # … as in the canister.yaml example above
    settings:
      environment_variables:
        __META_PROJECT: "My App"
        __META_NAME: "Backend"

Notes:

  • icp-cli merges these with the PUBLIC_CANISTER_ID:<name> variables it injects automatically at deploy time — the asset canister keeps serving and the app keeps working. (Verified against icp-cli 0.3.0.)
  • All values are strings; __META_MAIN_CANISTER must be the exact string "true".
  • They are applied during icp deploy (the "Setting environment variables" step). After deploy, confirm with icp canister settings show <name> -e ic.

Step 3 — Deploy to the engine's subnet

From the project root:

icp deploy -e ic --subnet <subnet-id>
  • -e ic targets mainnet (the engine runs on an IC subnet); --subnet <subnet-id> pins the deploy to your engine's subnet. Confirm the exact flags with icp deploy --help before running if unsure.
  • Deploying consumes capacity on the engine; make sure the engine has room.

Alternative — packaged upload. If the project is distributed as a built .icp package and a direct icp deploy is not available, upload the bundle on the console's App Center via "Upload a custom app" instead.

Step 4 — Verify

  • The icp deploy output reports the deployed canister ids.
  • The canisters appear on the engine's Applications page in the console; each canister's detail view offers an "Open in browser" link.
  • If you set the metadata in Step 2, the canisters are grouped under your __META_PROJECT name with their __META_NAME labels, and the main canister shows an "Open" button — instead of bare principal rows.
  • A frontend (asset) canister is served at https://<frontend-canister-id>.icp.net.

Report the deployed canister ids (and the frontend URL, if any) back to the user.

Common Pitfalls

1. Sign-in not completed. Running icp identity link web … but not finishing the Internet Identity sign-in in the browser leaves the CLI unlinked; later commands fail with authorization errors. Re-run and wait for the user to confirm the browser flow finished. If no browser ever opened, the command is stalled at the "Press Enter to log in" prompt — relaunch with a piped newline, printf '\n' | icp identity link web …, never < /dev/null (see Step 1). 2. Wrong `--auth` origin. Using any URL other than the console origin the user signs in with derives a different principal, and the engine rejects the deploy as not authorized. Relink with the exact console URL. If the deploy is rejected as unauthorized after linking against the default https://opencloud.org, ask the user for the exact URL they sign in with and relink. 3. Guessing the subnet id. Never invent it — the deploy fails or targets the wrong subnet. It is on the engine's App Center / Applications page; ask the user. 4. Deploying with the anonymous identity. The default local identity is anonymous and is not the engine admin. You must link and icp identity default <your-identity-name> first. 5. Using `dfx`. This ecosystem uses icp, never dfx. The correct sequence is icp identity link web <name> --auth <console-origin> (Step 1), then icp deploy -e ic --subnet <subnet-id> (Step 3). See the icp-cli skill. 6. Skipping the app metadata. Without __META_PROJECT (Step 2), the canisters still deploy and work but render as bare, unnamed principal rows in the console. Setting __META_* is what produces a named app with labelled canisters and an "Open" button. 7. Wrong `__META_MAIN_CANISTER` value. It is matched as the exact string "true". A boolean, "True", or marking more than one canister means no (or the wrong) "Open" button. Mark exactly one entry-point canister.

Related Skills

  • icp-cli — general icp CLI usage (icp.yaml, recipes, environments, bindings, identities). Load it for anything beyond this cloud-engine deploy flow.
  • internet-identity — details of the Internet Identity sign-in that Step 1 triggers in the browser.

Related skills

DevOps & CI/CDdeployinfra

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.