# Simulate a Migration in Docker
Make sure you have all you need before proceeding:
- You understand the concepts of migrations, production, and migrations in production.
- Docker is installed and you understand it.
- You have the checkers blockchain codebase up to the migrations. If not, follow the previous steps or check out the relevant version (opens new window).
In this section, you will:
- Prepare Docker elements.
- Deal with data migrations.
- Upgrade your blockchain in production with Cosmovisor.
- Compose everything in one orchestrated ensemble.
- Test it.
In previous sections, you have:
- Simulated a production setup with the help of Docker Compose.
- Learned how to implement an in-place migration.
This section is about:
- Running an in-place migration...
- ...in a simulated production setup...
- ...with the help of Docker Compose.
You will reuse the nodes, validators, and sentries created for Alice, Bob, and Carol in a previous section.
# What to expect
In this section, you will accomplish the following steps:
- Build the checkers v2 software.
- Build the checkers v1.1 software.
- Build the checkers v1 software.
- Build Cosmovisor and set it up for two consecutive known upgrades on all nodes.
- Launch everything.
- Create the first upgrade governance proposal,
v1tov1_1
. - Have the first proposal pass.
- Repeat with the second upgrade governance proposal,
v1_1tov2
. - Observe the first migration take place.
- Have the second proposal pass.
- Observe the second migration take place.
- Stop everything and start it again safely in v2.
In a real production situation, node operators would wait for a named upgrade governance proposal to be on the ballot (if not wait for it to be approved) before they went to the trouble of setting up Cosmovisor; therefore point 6 would happen some time before points 2 and 4. However, because we know that the proposal will go through, we will use the above order in the interest of time.
Also, both proposals will be created before the first upgrade, and the second proposal with be passed after the first upgrade. That is in the interest of the exercise, so as to see the second proposal cross the first upgrade in its pending state.
# Prepare checkers executables
At this stage, your checkers code already has the migration elements. It is therefore in its v2 configuration. Create the corresponding Docker image:
To build v1 and v1.1, you first need to check out the code before the migration code steps were added. Depending on your branch names, this would be:
Do not forget to come back to your v2 branch. For instance, with:
# Blockchain elements
Your genesis elements should still be in v1 as they were created in the run-prod
branch. You can confirm this by verifying that there are no player infos and no leaderboards in the checkers genesis store (opens new window).
As you did in the migration section, you need to reduce the voting period from 2 days to 10 minutes to make the exercise bearable:
The names of the upgrade proposals will be v1tov2_1
and v1_1tov2
. The names are important, as they are defined in the code, and Cosmovisor uses them to determine which executable to run.
# Prepare the Cosmovisor executable
Because the project in its current state uses Cosmos SDK v0.45.4, to avoid any surprise you will prepare Cosmovisor at the v0.45.4 (opens new window) version too.
You can describe the steps in a new Dockerfile prod-sim/Dockerfile-cosmovisor-alpine
, described here logically (before a recap lower down):
You need to build Cosmovisor from its code:
Cosmovisor is instructed via environment variables (opens new window). In the eventual containers, the
/root/.checkers
folder comes from a volume mount, so to avoid any conflict it is better not to put thecosmovisor
folder directly inside it. Instead pick/root/.checkers-upgrade
:With the folder decided, you can introduce all three checkers executables. They can be conveniently taken from their respective Docker images:
Checkers starts at v1, therefore the v1 executable goes into
.../genesis
. We know that:- The executable of the eventual upgrade named
v1tov1_1
is the v1.1 one. - The executable of the eventual upgrade named
v1_1tov2
is the v2 one.
Note also the decision to use
/usr/local
explicitly, as this is knowledge that is kept in a separate Docker image.- The executable of the eventual upgrade named
Now make Cosmovisor start by default:
When you put all this together, you get:
Now you can create the Cosmovisor Docker image with a meaningful tag:
# Docker Compose elements
With the executables and the blockchain elements ready, you can now define the production setup. You already defined one in the previous run checkers in prod section. In this new setup, the only things that change are the Docker images you call: cosmovisor_i
instead of checkersd_i
. Even the start
command does not need to change.
To avoid rewriting everything, you can declare a Docker Compose extension (opens new window) in a new file prod-sim/docker-compose-cosmovisor.yml
. Each checkersd
type of service is extended, and in the end is replaced, with a new image
:
docker-compose-cosmovisor.yml
's val-alice
extends docker-compose.yml
's val-alice
, while keeping the same name. In effect this overwrites val-alice
, instead of starting another validator working on the same shared prod-sim/val-alice
folder.
# Run all the elements
Now you can run everything and confirm that all services start:
In fact, at this stage there is no difference from the previous prod setup, which was what you now call v1. Blocks are being created.
Confirm you are on v1:
One way to confirm is to use checkers v1.1 to query Carol's node for the player infos:
It returns:
This confirms that the anwering node does not know about such structure.
Another way to confirm is to see to which folder Cosmovisor's
current
folder is symbolically linking:This should return:
Again, this confirms that it is running v1, as found in
.../genesis
.
# Add games
You will now need Alice and Bob's addresses, so take them from the keyrings found on their respective desktops.
The CosmJS tests use stake
and token
whereas this production setup uses only upawn
. Therefore, do a text search and change all occurrences of stake
and token
to upawn
in client/test/integration/stored-game-action.ts
(opens new window). Also remove the upawn: 1,
(opens new window) lines that prevent compilation.
Copying what you did in leaderboard migration section, credit the test accounts so that the CosmJS tests do not attempt to call a missing faucet:
Then run the tests. One run of the tests creates one completed game. It is okay do this multiple times:
Note how the RPC_URL
is passed via an environment variable. This uses the fact that dotenv
's config()
function does not overwrite existing variables.
The completed game will count for the future leaderboard.
# Prepare the upgrade proposals
Copying what was done in the previous migration section, with one block every 5 seconds, you make:
- The first upgrade proposal to be run in 15 minutes (i.e. 180 blocks).
- The second upgrade proposal to be run in 25 minutes (i.e. 300 blocks).
Remember that both proposals will have a voting period of 10 minutes, with the second one straddling the first upgrade:
- At t=0, the first proposal is in its voting period, for an upgrade 15 minutes later (t=+15 min).
- At t=+10 min, the first proposal should pass, and at about the same time, you create the second proposal (it does not matter if it is a bit before or a bit after) for an upgrade 15 minutes later (t=+25 min).
- At t=+15 min, the first upgrade happens automatically thanks to Cosmovisor. You will now be running v1.1.
- At t=+20 min, the second proposal should pass.
- At t=+25 min, the second upgrade happens. You will now be running v2.
Find the current block height with:
This returns something like:
# Send the first upgrade proposal
With a minimum deposit of 10,000,000 upawn, you can now have Alice send the governance proposal from her desktop to Carol's public node:
The command is long but it makes sense when you look at it carefully. It returns you the proposal id:
# Vote on the first proposal
Have both Alice and Bob vote "yes" on the proposal:
# Refill your cup
Wait 10 minutes from the time you created the first proposal.
When the proposal voting period ends, check that the votes went through and what the latest block height is:
The proposal's current status will be:
You must wait until after the proposal status changes to:
You must now wait longer, this time for the upgrade block to be reached. In the mean time...
# Send the second upgrade proposal
Between the time the first proposal has passed and the first upgrade takes place, send the second proposal, this time by Bob:
This returns you the second proposal id:
Similarly, have Alice and Bob vote on it:
# The first live upgrade
If you are scanning the logs of one of the containers, for instance from Docker's GUI, you should see something like:
That was v1's last message, followed by v1_1's first message.
After that, you should be able to query for the presence of player infos:
This should return:
You can also confirm that the leaderboard is still missing:
This still returns:
You can also verify with Cosmosvisor that it is now running v1.1:
This should return:
# The second live upgrade
You can follow the status of the second proposal with:
Observe that it changes to PASSED
after the first upgrade. After that, if you are scanning the logs of one of the containers (for instance from Docker's GUI) you should see something like:
That was v1.1's last message, followed by v2's first message. You can confirm that the leaderboard has been populated:
This returns:
# What about stop and restart?
All checkers containers are now running checkersd v2. You can see that Cosmovisor has swapped the current
executable:
This should return:
It will return this until the containers are stopped and deleted, that is.
Remember that the containers are loaded from a Docker image configured with Cosmovisor. In the current configuration, Cosmovisor starts with what it finds at genesis/bin/checkersd
, i.e. v1.
All this is to say that you should not expect it to work if you stop and start your Cosmovisor Compose setup as is.
If you were using real production servers, Cosmovisor's symbolic link would not reset itself on restart, so you would be safe in this regard. You would have time to revisit your server's configuration so as to launch checkersd
v2 natively.
In this example you can prepare yet another Compose file, this time specifically for v2:
Now you can safely stop the Cosmovisor setup:
And start the v2 setup:
If you want to test other migration configurations, for instance where Carol forgot to put Cosmovisor on her node, you can revert all your blockchain files to v1 with:
Another exercise you can attempt is create a v1tov2
upgrade that does both upgrades in one go. You would have to add this v1tov2
name into the Go code, and make sure it is handled correctly.
To summarize, this section has explored:
- How to prepare multi-stage Docker images for different executable versions.
- How to prepare Cosmovisor for a simulated production migration.
- How to upgrade a blockchain in production, by live migrating from v1 of the blockchain to v1.1 and then v2.
- How to launch all that with the help of Docker Compose.
- A complete procedure for how to conduct the update via the CLI.