Challenge, Medium,  on  Containers

Build a Container Image for Another Platform Using a Remote Builder

In the previous challenges, you built arm64 images from an amd64 host using QEMU emulation and cross-compilation. Both approaches run the build on the same machine where the docker build command is executed, sometimes with significant impact on performance.

In this challenge, you will practice the third approach: offloading the build to a remote machine with a (usually native) support for the target architecture. This is the most flexible approach, as it works for any language and any platform, and often it's also the fastest one.

The environment

  • dev-01 (this terminal) - your amd64 development machine with Docker installed. QEMU is not available on this machine.
  • builder-01 - a remote machine with Docker and arm64 build support, accessible via SSH as laborant@builder-01.
  • A private container registry at registry.iximiuz.com.

Explore the application

The ~/app/ directory contains a Node.js web server and a simple Dockerfile:

cat ~/app/server.js
cat ~/app/Dockerfile

The task

Your goal is to:

  1. Create a remote builder using Docker Buildx that runs on builder-01.
  2. Build the image for the linux/arm64 platform using that remote builder.
  3. Load the image into the dev-01 machine's local Docker daemon.
  4. Push the image to the playground's container registry as registry.iximiuz.com/app:v1.0.0.

In real-world scenarios, remote builders usually have native support for the target platform, but iximiuz Labs playgrounds don't yet support arm64 VMs. Therefore, the linux/arm64 support on builder-01 is provided via QEMU emulation. However, this should be fully transparent from the user's perspective - once you add a remote builder, its platform list will include linux/arm64, which is the only thing that matters for this particular exercise.

Create a remote builder

Use Docker Buildx to create a new builder that offloads builds to builder-01 via SSH.

Hint 1

Docker Buildx (docker buildx) can create and add remote builders to the local Docker daemon.

Check docker buildx create --help for the usage instructions.

Build, load, and push the image

Once your remote builder is ready, build the registry.iximiuz.com/app:v1.0.0 image for the linux/arm64 platform and make sure it's both loaded into the local Docker daemon and pushed to the playground's container registry.

Hint 2

When an image is built remotely, it doesn't always appear in the docker images output of the local Docker daemon. Depending on the docker build command configuration, you may need to explicitly specify the --load flag to load the image from the remote builder into the local Docker's image store.

Hint 3

There are several ways to push a remotely built image to a registry.

For instance, you can load the image into the local Docker daemon and then push it to the registry using the most basic docker push command. Works especially well when the remote builder is not authorized to push directly to the registry.

However, if remote builders have push access to the registry, and the image is not needed locally, or the build time is critical, you can push the image directly to the registry using docker build --push.

Hint 4

Don't forget to use the --platform linux/arm64 flag while building the image.

Even if you explicitly specify the remote builder via docker build --builder, the resulting image may still be built for a wrong architecture if the remote builder supports several platforms.

Application test

The image will be pulled and tested on a separate machine: