Skip to content

Commit 70b034e

Browse files
feat: canister migration tutorial (#6160)
* feat: canister migration tutorial * codeowners * docs * fixes * canister settings migration * drop user name * Update docs/building-apps/advanced/canister-migration.mdx Co-authored-by: Stefan Schneider <31004026+schneiderstefan@users.noreply.github.com> * note about dfx identity get-wallet and set-wallet * links * timestamp * set-wallet force * bump dfinity/sdk * pin dfinity/sdk to 0.31.0-beta.0 * fix CI --------- Co-authored-by: Stefan Schneider <31004026+schneiderstefan@users.noreply.github.com>
1 parent 540a570 commit 70b034e

File tree

5 files changed

+127
-3
lines changed

5 files changed

+127
-3
lines changed

.github/CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ docs/building-apps/essentials/message-execution.mdx @dfinity/team-dsm @dfinity/e
3333
docs/building-apps/network-features/simd.mdx @dfinity/team-dsm @dfinity/editorial
3434
docs/building-apps/network-features/periodic-tasks-timers.mdx @dfinity/team-dsm @dfinity/editorial
3535
docs/building-apps/canister-management/backtraces.mdx @dfinity/team-dsm @dfinity/editorial
36+
docs/building-apps/advanced/canister-migration.mdx @dfinity/team-dsm @dfinity/editorial
3637

3738
# Boundary Node
3839
docs/building-apps/frontends/custom-domains/ @dfinity/boundary-node @dfinity/editorial

.github/workflows/check_submodule.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ jobs:
1919
# Submodules are very easy to accidentally overwrite with old versions.
2020
# To make submodule updates more explicit and to prevent accidental changes we check the revisions explicitly here.
2121
22-
# dfx 0.30.2
23-
LATEST_SDK="3b404c23abbc91602b96a143aa836a001818e6fb"
22+
# dfx 0.31.0-beta.0
23+
LATEST_SDK="baae15c16633776eae8135f511932f1646018186"
2424
2525
# motoko docs 0.16.3
2626
LATEST_MOTOKO="0d60c0f415c8f9330d881f551ef978fcf5afb353"
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
---
2+
keywords: [intermediate, dfx, load balancing, migration]
3+
---
4+
5+
import { MarkdownChipRow } from "/src/components/Chip/MarkdownChipRow";
6+
7+
# Canister Migration
8+
9+
<MarkdownChipRow labels={["Intermediate"]} />
10+
11+
# Overview
12+
13+
*Canister migration* refers to moving a canister (called the "migrated" canister) from one subnet (called "source" subnet) to another subnet (called "target" subnet).
14+
This tutorial covers migrating the canister settings, state (WASM, main and stable memory, etc.), cycles, and canister ID (principal).
15+
Transient state (canister logs and history) and cycles reserved for storage cannot be migrated from one subnet to another.
16+
17+
The target subnet must contain a canister (called the "replaced" canister) that is used as a placeholder throughout canister migration.
18+
For instance, this canister can be created using [`dfx canister create`](/building-apps/developer-tools/dfx/dfx-canister#dfx-canister-create).
19+
20+
# Requirements
21+
22+
The following tutorial assumes `dfx` at version at least 0.31.0-beta.0.
23+
24+
# Canister Settings Migration
25+
26+
Canister settings can be migrated using [`dfx canister update-settings`](/building-apps/developer-tools/dfx/dfx-canister#dfx-canister-update-settings) specifying the migrated canister as `--sync-with` and the replaced canister as the canister whose settings are updated.
27+
28+
# Canister State Migration
29+
30+
The canister state of the migrated canister must first be captured by [creating a canister snapshot](/building-apps/canister-management/snapshots/#creating-a-snapshot).
31+
32+
The canister snapshot can then be downloaded to a local file directory using [`dfx canister snapshot download`](/building-apps/developer-tools/dfx/dfx-canister#dfx-canister-snapshot-download).
33+
34+
Next the canister snapshot can be uploaded to the replaced canister using [`dfx canister snapshot upload`](/building-apps/developer-tools/dfx/dfx-canister#dfx-canister-snapshot-upload).
35+
36+
Finally the canister snapshot can be [loaded](/docs/tutorials/developer-liftoff-rust/level-3/3.3-canister-snapshots/#loading-a-snapshot) to the replaced canister.
37+
38+
The loaded canister snapshot of the replaced canister must be deleted using [`dfx canister snapshot delete`](/docs/tutorials/developer-liftoff-rust/level-3/3.3-canister-snapshots/#deleting-a-snapshot) before proceeding with canister ID migration (see below).
39+
It is recommended to preserve the snapshot of the migrated canister (and also its copy in a local file directory) to facilitate disaster recovery.
40+
41+
# Canister Cycles Migration
42+
43+
**WARNING**: Make sure to create a snapshot of the migrated canister before proceeding with the following commands since they will destroy the migrated canister's state.
44+
45+
To prepare for cycles migration, we first uninstall the migrated canister using [`dfx canister uninstall-code`](/building-apps/developer-tools/dfx/dfx-canister#dfx-canister-uninstall-code) and then we deploy the cycles wallet (WASM) to the migrated canister using [`dfx identity deploy-wallet`](/building-apps/developer-tools/dfx/dfx-identity#dfx-identity-deploy-wallet) (the canister ID must be provided explicitly, i.e., the argument of `dfx identity deploy-wallet` must not be a canister name). It is recommended to check and remember the current wallet using [`dfx identity get-wallet`](/building-apps/developer-tools/dfx/dfx-identity#dfx-identity-get-wallet) before running `dfx identity deploy-wallet` (to prevent forgetting the canister ID of the currently configured wallet if applicable).
46+
47+
To actually migrate cycles from the migrated canister, we use [`dfx canister deposit-cycles`](/building-apps/developer-tools/dfx/dfx-canister#dfx-canister-deposit-cycles) specifying the migrated canister as `--wallet` (the canister ID must be provided explicitly, i.e., the argument of `--wallet` must not be a canister name) and the replaced canister as the canister to which cycles should be deposited.
48+
49+
Finally, restore your previous wallet using [`dfx identity set-wallet`](/building-apps/developer-tools/dfx/dfx-identity#dfx-identity-set-wallet) and the wallet canister ID obtained previously using `dfx identity get-wallet`.
50+
51+
Make sure to leave at least 10T cycles in the migrated canister to pay for canister ID migration (described in the next section) and additionally enough cycles to pay for the migrated canister's resource consumption up until its canister ID migration. You can check out the migrated canister's resource cycles consumption as "idle" cycles consumption (per day) using [`dfx canister status`](/building-apps/developer-tools/dfx/dfx-canister#dfx-canister-status).
52+
53+
# Canister ID Migration
54+
55+
**WARNING**: Make sure that the migrated canister's state has been loaded to the replaced canister (see the above section on Canister State Migration) before proceeding with canister ID migration since it will destroy the migrated canister's state.
56+
57+
To prepare for canister ID migration, we stop both the migrated and replaced canisters using [`dfx canister stop`](/building-apps/developer-tools/dfx/dfx-canister#dfx-canister-stop).
58+
59+
Then we can kick off canister ID migration using [`dfx canister migrate-id`](/building-apps/developer-tools/dfx/dfx-canister#dfx-canister-migrate-id) specifying the migrated canister ID as the canister ID to migrate and the replaced canister ID as `--replace`.
60+
61+
Canister ID migration is expected to take at least 6 minutes. You can check out its status using [`dfx canister migration-status`](/building-apps/developer-tools/dfx/dfx-canister#dfx-canister-migration-status).
62+
63+
# Example
64+
65+
Here's a complete example runbook for canister migration.
66+
The migrated canister ID is `uqqxf-5h777-77774-qaaaa-cai` and the replaced canister ID is `ahree-maaaa-aaaar-q777q-cai`.
67+
```
68+
# Canister Settings Migration
69+
$ dfx canister update-settings replaced --sync-with migrated
70+
Canister settings: migrated
71+
...
72+
73+
WARNING!
74+
You are trying to sync settings from 'migrated' to 'replaced'.
75+
Do you want to proceed? yes/No
76+
yes
77+
Synced settings from 'migrated' to 'replaced'.
78+
79+
# Canister State Migration
80+
$ dfx canister stop migrated
81+
Stopping code for canister migrated, with canister_id uqqxf-5h777-77774-qaaaa-cai
82+
$ dfx canister snapshot create migrated
83+
Created a new snapshot of canister migrated. Snapshot ID: 0000000000000000ffffffffff9000000101
84+
$ dfx canister snapshot download --dir snapshot_dir migrated 0000000000000000ffffffffff9000000101
85+
Snapshot 0000000000000000ffffffffff9000000101 in canister migrated saved to 'snapshot_dir'
86+
$ dfx canister snapshot upload --dir snapshot_dir replaced
87+
Uploaded a snapshot of canister replaced. Snapshot ID: 0000000000000000000000000230ffff0101
88+
$ dfx canister stop replaced
89+
Stopping code for canister replaced, with canister_id ahree-maaaa-aaaar-q777q-cai
90+
$ dfx canister snapshot load replaced 0000000000000000000000000230ffff0101
91+
Loaded snapshot 0000000000000000000000000230ffff0101 in canister replaced
92+
$ dfx canister snapshot delete replaced 0000000000000000000000000230ffff0101
93+
Deleted snapshot 0000000000000000000000000230ffff0101 from canister replaced
94+
95+
# Canister Cycles Migration
96+
$ dfx canister uninstall-code migrated
97+
Uninstalling code for canister migrated, with canister_id uqqxf-5h777-77774-qaaaa-cai
98+
$ dfx canister start migrated
99+
Starting code for canister migrated, with canister_id uqqxf-5h777-77774-qaaaa-cai
100+
$ WALLET="$(dfx identity get-wallet)"
101+
$ dfx identity deploy-wallet uqqxf-5h777-77774-qaaaa-cai
102+
Created a wallet canister on the "local" network for user ... with ID "uqqxf-5h777-77774-qaaaa-cai"
103+
$ dfx canister deposit-cycles --wallet uqqxf-5h777-77774-qaaaa-cai 89_000_000_000_000 replaced
104+
Depositing 89000000000000 cycles onto replaced
105+
Deposited 89000000000000 cycles.
106+
$ dfx identity set-wallet "${WALLET}" --force
107+
Skipping verification of availability of the canister on the network due to --force...
108+
Setting wallet for identity ... on network 'local' to id 'uqqxf-5h777-77774-qaaaa-cai'
109+
Wallet set successfully.
110+
111+
# Canister ID Migration
112+
$ dfx canister stop migrated
113+
Stopping code for canister migrated, with canister_id uqqxf-5h777-77774-qaaaa-cai
114+
$ dfx canister stop replaced
115+
Stopping code for canister replaced, with canister_id ahree-maaaa-aaaar-q777q-cai
116+
$ dfx canister migrate-id migrated --replace replaced
117+
WARNING!
118+
Canister 'migrated' will be removed from its own subnet. Continue?
119+
Do you want to proceed? yes/No
120+
yes
121+
Migration succeeded at 2026-01-22 10:50:36 UTC
122+
```

sidebars.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ const sidebars = {
258258
type: "category",
259259
label: "Advanced development",
260260
items: [
261+
"building-apps/advanced/canister-migration",
261262
"building-apps/advanced/using-third-party-canisters",
262263
"building-apps/advanced/benchmarking",
263264
{

submodules/sdk

Submodule sdk updated 64 files

0 commit comments

Comments
 (0)