Skip to content

Commit d892753

Browse files
authored
Merge pull request #2910 from ajeetraina/docker-mcp-toolkit-learning-path
Add Docker MCP Toolkit Arm migration learning path
2 parents c0b9095 + a6ebf01 commit d892753

7 files changed

Lines changed: 577 additions & 0 deletions

File tree

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
---
2+
title: The Arm migration challenge and how Docker MCP Toolkit solves it
3+
weight: 2
4+
5+
### FIXED, DO NOT MODIFY
6+
layout: learningpathall
7+
---
8+
9+
## Why migrate to Arm?
10+
11+
Moving workloads from x86 to Arm64 has become a priority for organizations looking to reduce cloud costs and improve performance. AWS Graviton, Azure Cobalt, and Google Cloud Axion have made Arm-based computing mainstream, offering 20-40% cost savings and improved performance-per-watt for many workloads.
12+
13+
The challenge is that migration is not always straightforward. For most containerized applications, rebuilding a Docker image for Arm64 is enough. But when you encounter legacy applications with hand-optimized x86 assembly, AVX2 intrinsics, or architecture-specific compiler flags, the migration becomes significantly more complex.
14+
15+
## What makes x86-to-Arm migration hard?
16+
17+
Traditional migration approaches require:
18+
19+
- Manual code analysis for x86-specific dependencies.
20+
- Tedious compatibility checks across multiple tools.
21+
- Researching Arm NEON equivalents for each x86 intrinsic.
22+
- Rewriting vectorized code and adjusting loop structures.
23+
- Updating Dockerfiles, base images, and compiler flags.
24+
- Debugging compilation errors on the new architecture.
25+
26+
For a single application with SIMD-optimized code, this can take 5-7 hours of manual work.
27+
28+
## What the Docker MCP Toolkit provides
29+
30+
The Docker MCP Toolkit is a management interface in Docker Desktop that lets you discover, configure, and run containerized MCP (Model Context Protocol) servers. It connects these servers to AI coding assistants through a unified gateway.
31+
32+
For Arm migration, three MCP servers work together:
33+
34+
- **Arm MCP Server**: Provides code scanning (`migrate_ease_scan`), Docker image architecture checking (`check_image`, `skopeo`), Arm knowledge base search (`knowledge_base_search`), and assembly performance analysis (`mca`).
35+
- **GitHub MCP Server**: Enables repository operations including creating pull requests, managing branches, and committing changes.
36+
- **Sequential Thinking MCP Server**: Helps the AI assistant break down complex migration decisions into logical steps.
37+
38+
## How AI-assisted migration works
39+
40+
When connected to the Docker MCP Toolkit, an AI coding assistant like GitHub Copilot can execute the entire migration workflow:
41+
42+
1. Use `check_image` or `skopeo` to verify if base images support `linux/arm64`.
43+
2. Run `migrate_ease_scan` on the codebase to find x86-specific code, intrinsics, and compiler flags.
44+
3. Use `knowledge_base_search` to find correct Arm SIMD equivalents for every x86 intrinsic.
45+
4. Convert the code with architecture-specific accuracy.
46+
5. Update the Dockerfile with Arm-compatible base images and compiler flags.
47+
6. Create a pull request with all changes using the GitHub MCP Server.
48+
49+
What normally takes 5-7 hours of manual work takes about 25-30 minutes.
50+
51+
## What you will build in this Learning Path
52+
53+
In this Learning Path, you will migrate a real-world legacy application - a matrix multiplication benchmark written with AVX2 intrinsics for x86 - to Arm64 using GitHub Copilot and Docker MCP Toolkit.
54+
55+
The demo repository is available at [github.com/JoeStech/docker-blog-arm-migration](https://github.com/JoeStech/docker-blog-arm-migration).
56+
57+
You will:
58+
59+
1. Set up Docker MCP Toolkit with the Arm, GitHub, and Sequential Thinking MCP servers.
60+
2. Connect VS Code with GitHub Copilot to the MCP Gateway.
61+
3. Analyze the legacy x86 codebase to understand what blocks Arm migration.
62+
4. Use AI-driven tools to automate the full migration.
63+
5. Review the pull request created by the AI agent.
64+
65+
In the next section, you will install and configure the Docker MCP Toolkit.
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
---
2+
title: Set up Docker MCP Toolkit with Arm, GitHub, and Sequential Thinking servers
3+
weight: 3
4+
5+
### FIXED, DO NOT MODIFY
6+
layout: learningpathall
7+
---
8+
9+
## Before you begin
10+
11+
You need:
12+
13+
- Docker Desktop 4.59 or later.
14+
- VS Code with the GitHub Copilot extension.
15+
- A GitHub account with a personal access token.
16+
- A machine with at least 8 GB RAM (16 GB recommended).
17+
18+
## Enable the Docker MCP Toolkit
19+
20+
1. Open Docker Desktop.
21+
2. Go to **Settings** > **Beta features**.
22+
3. Toggle **Enable Docker MCP Toolkit** on.
23+
4. Click **Apply**.
24+
25+
After a few seconds, the **MCP Toolkit** tab appears in the left sidebar.
26+
27+
## Add the required MCP servers
28+
29+
Open the **MCP Toolkit** in Docker Desktop and select the **Catalog** tab. Add the following three servers:
30+
31+
### Arm MCP Server
32+
33+
Search for **Arm** in the catalog and add the [Arm MCP Server](https://hub.docker.com/mcp/server/arm-mcp/overview).
34+
35+
Configure it by setting the directory path to your local code. This allows the `migrate_ease_scan` and `mca` tools to access your source files. Click **Save** after setting the path.
36+
37+
The Arm MCP Server provides six tools:
38+
39+
| Tool | Description |
40+
|------|-------------|
41+
| `knowledge_base_search` | Semantic search of Arm learning resources, intrinsics documentation, and software compatibility |
42+
| `migrate_ease_scan` | Code scanner for C++, Python, Go, JavaScript, and Java Arm compatibility analysis |
43+
| `check_image` | Docker image architecture verification for Arm64 support |
44+
| `skopeo` | Remote container image inspection without downloading |
45+
| `mca` | Machine Code Analyzer for assembly performance and IPC predictions |
46+
| `sysreport_instructions` | System architecture information gathering |
47+
48+
### GitHub Official MCP Server
49+
50+
Search for **GitHub Official** in the catalog and add the [GitHub MCP Server](https://hub.docker.com/mcp/server/github-official/overview).
51+
52+
Configure authentication:
53+
54+
1. Select the GitHub Official server.
55+
2. Choose **Personal Access Token** as the authentication method.
56+
3. Enter your GitHub token from **GitHub Settings** > **Developer Settings** > **Personal access tokens**.
57+
58+
This server lets GitHub Copilot create pull requests, manage issues, and commit changes directly to your repositories.
59+
60+
### Sequential Thinking MCP Server
61+
62+
Search for **Sequential Thinking** in the catalog and add the [Sequential Thinking MCP Server](https://hub.docker.com/mcp/server/sequentialthinking/overview).
63+
64+
No configuration is needed. This server helps GitHub Copilot break down complex migration decisions into logical steps.
65+
66+
## Connect VS Code to the MCP Gateway
67+
68+
1. In Docker Desktop, go to **MCP Toolkit** > **Clients** tab.
69+
2. Scroll to **Visual Studio Code** and click **Connect**.
70+
3. Open VS Code and click the **Extensions** icon in the left toolbar.
71+
4. Find **MCP_DOCKER**, click the gear icon, and click **Start Server**.
72+
73+
## Verify the connection
74+
75+
Open GitHub Copilot Chat in VS Code and ask:
76+
77+
```text
78+
What Arm migration tools do you have access to?
79+
```
80+
81+
You should see tools from all three servers listed. If they appear, your setup is complete.
82+
83+
In the next section, you will examine the demo application to understand what blocks its migration to Arm64.
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
---
2+
title: Understand the legacy x86 demo application
3+
weight: 4
4+
5+
### FIXED, DO NOT MODIFY
6+
layout: learningpathall
7+
---
8+
9+
## Clone the demo repository
10+
11+
The demo application is a matrix multiplication benchmark written in C++ with AVX2 intrinsics. Clone it:
12+
13+
```bash
14+
git clone https://github.com/JoeStech/docker-blog-arm-migration
15+
cd docker-blog-arm-migration
16+
```
17+
18+
## Examine the Dockerfile
19+
20+
Open the `Dockerfile`. There are two immediate blockers for Arm migration:
21+
22+
**No Arm64 support in the base image**: The `centos:6` image was built for x86 only. This container will not start on Arm hardware.
23+
24+
**x86-specific compiler flag**: The `-mavx2` flag tells the compiler to use AVX2 vector instructions, which do not exist on Arm processors.
25+
26+
```dockerfile
27+
FROM centos:6
28+
29+
RUN yum install -y \
30+
devtoolset-2-gcc \
31+
devtoolset-2-gcc-c++ \
32+
devtoolset-2-binutils \
33+
make \
34+
&& yum clean all
35+
36+
WORKDIR /app
37+
COPY *.h *.cpp ./
38+
39+
RUN scl enable devtoolset-2 "g++ -O2 -mavx2 -o benchmark \
40+
main.cpp \
41+
matrix_operations.cpp \
42+
-std=c++11"
43+
44+
CMD ["./benchmark"]
45+
```
46+
47+
## Examine the source code
48+
49+
Open `matrix_operations.cpp`. The code uses x86 AVX2 intrinsics throughout:
50+
51+
```cpp
52+
#include <immintrin.h> // x86-only header
53+
54+
// Inside the multiply function:
55+
__m256d sum_vec = _mm256_setzero_pd();
56+
__m256d a_vec = _mm256_loadu_pd(&data[i][k]);
57+
sum_vec = _mm256_add_pd(sum_vec, _mm256_mul_pd(a_vec, b_vec));
58+
59+
// Horizontal reduction
60+
__m128d sum_high = _mm256_extractf128_pd(sum_vec, 1);
61+
__m128d sum_low = _mm256_castpd256_pd128(sum_vec);
62+
```
63+
64+
## Why this code cannot run on Arm
65+
66+
There are several specific blockers:
67+
68+
1. **x86-exclusive header**: `#include <immintrin.h>` only exists on x86 systems. Arm uses `<arm_neon.h>` instead.
69+
70+
2. **AVX2 intrinsics throughout**: Every `_mm256_*` function is Intel-specific:
71+
- `_mm256_setzero_pd()` creates a 256-bit zero vector (Arm NEON is 128-bit).
72+
- `_mm256_loadu_pd()` loads 4 doubles at once (NEON loads 2 with `vld1q_f64`).
73+
- `_mm256_add_pd()` and `_mm256_mul_pd()` are 256-bit operations (NEON uses 128-bit equivalents).
74+
- `_mm256_extractf128_pd()` extracts the high 128 bits (not needed on NEON).
75+
76+
3. **Vector width mismatch**: AVX2 processes 4 doubles per operation. Arm NEON processes 2 doubles per operation. The entire loop structure needs adjustment.
77+
78+
{{% notice Note %}}
79+
SVE/SVE2 on newer Arm cores (Neoverse V1/V2, Graviton 3/4) provides 256-bit or wider vector-length agnostic (VLA) registers, matching or exceeding AVX2 width. The Arm MCP Server knowledge base can help determine the best approach for your target hardware.
80+
{{% /notice %}}
81+
82+
4. **Horizontal reduction logic**: The pattern using `_mm256_extractf128_pd` and `_mm256_castpd256_pd128` is x86-specific and must be completely rewritten.
83+
84+
Manual conversion requires rewriting 30+ lines of intrinsic code, adjusting loop strides, and testing numerical accuracy. This is exactly where the Docker MCP Toolkit with the Arm MCP Server becomes essential.
85+
86+
In the next section, you will use GitHub Copilot with the Docker MCP Toolkit to automate the entire migration.
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
---
2+
title: Run the AI-driven Arm migration
3+
weight: 5
4+
5+
### FIXED, DO NOT MODIFY
6+
layout: learningpathall
7+
---
8+
9+
## Open the project in VS Code
10+
11+
Open the cloned `docker-blog-arm-migration` directory in VS Code:
12+
13+
```bash
14+
cd docker-blog-arm-migration
15+
code .
16+
```
17+
18+
Make sure the MCP_DOCKER server is running in VS Code (check **Extensions** > **MCP_DOCKER** > **Start Server** if needed).
19+
20+
## Give GitHub Copilot migration instructions
21+
22+
Open GitHub Copilot Chat in VS Code and paste the following prompt:
23+
24+
```text
25+
Your goal is to migrate this codebase from x86 to Arm64. Use the Arm MCP
26+
Server tools to help you with this migration.
27+
28+
Steps to follow:
29+
1. Check all Dockerfiles - use check_image and/or skopeo tools to verify
30+
Arm compatibility, changing the base image if necessary
31+
2. Scan the codebase - run migrate_ease_scan with the appropriate language
32+
scanner and apply the suggested changes
33+
3. Use knowledge_base_search when you need Arm architecture guidance or
34+
intrinsic equivalents
35+
4. Update compiler flags and dependencies for Arm64 compatibility
36+
5. Create a pull request with all changes using GitHub MCP Server
37+
38+
Important notes:
39+
- Your current working directory is mapped to /workspace on the MCP server
40+
- NEON lane indices must be compile-time constants, not variables
41+
- If unsure about Arm equivalents, use knowledge_base_search to find docs
42+
- Be sure to find out from the user or system what the target machine is,
43+
and use the appropriate intrinsics. For instance, if neoverse (Graviton,
44+
Axion, Cobalt) is targeted, use the latest SME/SME2.
45+
46+
After completing the migration:
47+
- Create a pull request with a detailed description of changes
48+
- Include performance predictions and cost savings in the PR description
49+
- List all tools used and validation steps needed
50+
```
51+
52+
## Watch the migration execute
53+
54+
GitHub Copilot orchestrates the migration through four phases using the Docker MCP Toolkit.
55+
56+
### Phase 1: Image analysis
57+
58+
Copilot uses the `skopeo` tool from the Arm MCP Server to analyze the base image:
59+
60+
```text
61+
Checking centos:6 for arm64 support...
62+
```
63+
64+
The tool reports that `centos:6` has no `linux/arm64` build available. This is the first blocker identified. Copilot determines that the base image must be replaced.
65+
66+
### Phase 2: Code scanning
67+
68+
Copilot runs the `migrate_ease_scan` tool with the C++ scanner:
69+
70+
```text
71+
Running migrate_ease_scan with scanner: cpp
72+
```
73+
74+
The scan detects:
75+
76+
- AVX2 intrinsics (`_mm256_*` functions) in `matrix_operations.cpp`.
77+
- The `-mavx2` compiler flag in the Dockerfile.
78+
- The x86-specific header `<immintrin.h>`.
79+
80+
Each issue includes the file location, line number, and specific code requiring modification.
81+
82+
### Phase 3: Knowledge base lookup and code conversion
83+
84+
For each x86 intrinsic found, Copilot queries the Arm MCP Server knowledge base:
85+
86+
```text
87+
Searching knowledge base for: AVX2 to NEON intrinsic conversion
88+
```
89+
90+
The knowledge base returns Arm documentation with the conversions:
91+
92+
| x86 AVX2 Intrinsic | Arm NEON Equivalent |
93+
|---------------------|---------------------|
94+
| `_mm256_setzero_pd()` | Two `vdupq_n_f64(0.0)` operations |
95+
| `_mm256_loadu_pd()` | Two `vld1q_f64()` loads |
96+
| `_mm256_add_pd()` | Two `vaddq_f64()` operations |
97+
| `_mm256_mul_pd()` | Two `vmulq_f64()` operations |
98+
99+
The knowledge base also explains that AVX2 uses 256-bit vectors processing 4 doubles at once, while NEON uses 128-bit vectors processing 2 doubles. Loop strides must be adjusted accordingly.
100+
101+
Copilot rewrites the code using this information:
102+
103+
- Replaces `<immintrin.h>` with `<arm_neon.h>` inside `#ifdef __aarch64__` guards.
104+
- Converts the AVX2 loop structure (stride 4) to NEON (stride 2).
105+
- Rewrites the horizontal reduction for NEON.
106+
- Updates the Dockerfile to use `ubuntu:22.04` with `TARGETARCH` for multi-arch builds.
107+
- Changes the compiler flag from `-mavx2` to `-march=armv8-a+simd`.
108+
109+
### Phase 4: Create the pull request
110+
111+
Copilot uses the GitHub MCP Server to create a pull request with:
112+
113+
- All code changes (source files and Dockerfile).
114+
- A detailed description of what was changed and why.
115+
- Performance predictions for Arm.
116+
- A list of all MCP tools used during the migration.
117+
118+
You can see an example PR at [github.com/JoeStech/docker-blog-arm-migration/pull/1](https://github.com/JoeStech/docker-blog-arm-migration/pull/1).
119+
120+
## Summary of changes
121+
122+
The migration produces these key changes:
123+
124+
**Dockerfile**:
125+
- Replaced `centos:6` with `ubuntu:22.04`.
126+
- Added `TARGETARCH` for multi-architecture builds.
127+
- Changed `-mavx2` to `-march=armv8-a+simd` for Arm builds.
128+
129+
**Source code**:
130+
- Added `#ifdef __aarch64__` architecture guards.
131+
- Replaced all `_mm256_*` AVX2 intrinsics with NEON equivalents (`vld1q_f64`, `vaddq_f64`, `vmulq_f64`).
132+
- Adjusted loop strides from 4 (AVX2) to 2 (NEON).
133+
- Rewrote horizontal reduction using NEON pair-wise addition.
134+
135+
In the next section, you will build, test, and validate the migrated application on Arm.

0 commit comments

Comments
 (0)