Arm Community
Arm Community
  • Site
  • User
  • Site
  • Search
  • User
Arm Community blogs
Arm Community blogs
Tools, Software and IDEs blog Getting started with Docker for Arm using buildx on Linux
  • Blogs
  • Mentions
  • Sub-Groups
  • Tags
  • Jump...
  • Cancel
More blogs in Arm Community blogs
  • AI blog

  • Announcements

  • Architectures and Processors blog

  • Automotive blog

  • Embedded and Microcontrollers blog

  • Internet of Things (IoT) blog

  • Laptops and Desktops blog

  • Mobile, Graphics, and Gaming blog

  • Operating Systems blog

  • Servers and Cloud Computing blog

  • SoC Design and Simulation blog

  • Tools, Software and IDEs blog

Tags
  • Embedded Linux
  • Docker
  • Application Software
  • Tutorial
Actions
  • RSS
  • More
  • Cancel
Related blog posts
Related forum threads

Getting started with Docker for Arm using buildx on Linux

Jason Andrews
Jason Andrews
June 13, 2019
8 minute read time.

Arm and Docker announced a strategic partnership earlier this year to unify software development and deployment across a diverse set of devices, from IoT endpoints to the edge of the network, and into the heart of the data center.

The Arm/Docker presentation in the ecosystem track at DockerCon 2019 demonstrated the latest features for Arm software development using Docker Desktop for Windows and Mac. If you missed it, here are some articles to review:

  • Arm and Docker: Better Together
  • Getting started with Docker on Arm
  • Cross building Arm images on Docker Desktop
  • Multiarch docker builds
  • Building Multi-Arch Images for Arm and x86 with Docker Desktop

The good news is the same capability is available on Linux. Although Windows and Mac support is great, the majority of software developers targeting embedded Linux systems also do their development work on Linux. The multi-architecture support in Docker simplifies embedded Linux application development and deployment when targeting embedded Arm systems. 

If you are doing software development on x86 Linux machines and want to create Docker images that run on Arm servers or Arm embedded and IoT devices, this article will be helpful to understand the process and the different ways to do it.

Let’s see how to use Docker for Arm software development using the new buildx feature on Linux to create multi-architecture container images and run them. I’m using Ubuntu 18.04, but the same info applies to most any Linux distribution.

Install Docker

Installing Docker on Linux takes just a few commands. More installation info is available in the Docker Documentation.

Using buildx requires docker 19.03. Today, the best way to get this is using the test channel instead of the stable version.

$ sudo apt-get update
$ sudo apt-get -y upgrade
$ curl -fsSL test.docker.com -o get-docker.sh && sh get-docker.sh

If an older version of Docker (or the current stable version) is already installed you may see a warning when the install script is run:

# Executing docker install script, commit: 2f4ae48
Warning: the "docker" command appears to already exist on this system.

If you already have Docker installed, this script can cause trouble, which is
why we're displaying this warning and provide the opportunity to cancel the
installation.

If you installed the current Docker package using this script and are using it
again to update Docker, you can safely ignore this message.

You may press Ctrl+C now to abort this script.
+ sleep 20

To correct this hit Ctrl-C top stop the install script and just change the repository from stable to test by editing the file /etc/apt/sources.list.d/docker.list

The updated file should be:

deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic test

Now uninstall the older version and install the test version. 

$ sudo apt update
$ sudo apt remove -y docker-ce docker-ce-cli containerd.io    
$ sudo apt install -y docker-ce docker-ce-cli containerd.io

It's also recommended to add the current user to the docker group to avoid needing sudo to run docker commands. Without this all docker commands need to be run as root or with sudo.

$ sudo usermod -aG docker $USER

Make sure to log out and back in again for user accounts to appear in the docker group. Now test the install with a quick hello-world run.

$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
1b930d010525: Pull complete 
Digest: sha256:6f744a2005b12a704d2608d8070a494ad1145636eeb74a570c56b94d94ccdbfc
Status: Downloaded newer image for hello-world:latest
 
Hello from Docker!
This message shows that your installation appears to be working correctly.
 
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.
 
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
 
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
 
For more examples and ideas, visit:
https://docs.docker.com/get-started/

Use the docker version command to check the running version:

$ docker version
Client: Docker Engine - Community
 Version:           19.03.0-rc2
 API version:       1.40
 Go version:        go1.12.4
 Git commit:        f97efcc806
 Built:             Wed Jun  5 01:40:57 2019
 OS/Arch:           linux/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          19.03.0-rc2
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.12.4
  Git commit:       f97efcc806
  Built:            Wed Jun  5 01:39:32 2019
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.2.6
  GitCommit:        894b81a4b802e4eb2a91d1ce216b8817763c29fb
 runc:
  Version:          1.0.0-rc8
  GitCommit:        425e105d5a03fabd737a126ad93d62a9eeede87f
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683

Install buildx for multi-architecture image creation

There are three options to get buildx on Linux:

  • Use buildx directly from the test version of docker
  • Download a binary release of buildx and copy it to the $HOME/.docker directory
  • Download, build, and install buildx from github.com

Use buildx from Docker test

The test version of Docker already has buildx included. The only thing needed is to set the environment variable to enable experimental command line features.

$ export DOCKER_CLI_EXPERIMENTAL=enabled

Download a binary release

Another way to get buildx is to download a binary release from github and put in the .docker/cli-plugins directory.

For example, download the buildx for Linux amd64 with a browser from: https://github.com/docker/buildx/releases/tag/v0.2.0

Then copy it to the cli-plugins/ directory:

$ cp buildx-v0.2.0.linux-amd64 ~/.docker/cli-plugins/docker-buildx

Download, build, and install buildx

Because buildx is a new command and documentation is still catching up, github is a good place to read more information about how buildx works.

The last way to get buildx is from github using the commands:

$ export DOCKER_BUILDKIT=1
$ docker build --platform=local -o . git://github.com/docker/buildx
$ mkdir -p ~/.docker/cli-plugins
$ mv buildx ~/.docker/cli-plugins/docker-buildx

After using one of the above methods, confirm buildx is installed by running the help and the version commands.

$ docker buildx --help
 
Usage:    docker buildx COMMAND
 
Build with BuildKit
 
Management Commands:
  imagetools  Commands to work on images in registry
 
Commands:
  bake        Build from a file
  build       Start a build
  create      Create a new builder instance
  inspect     Inspect current builder instance
  ls          List builder instances
  rm          Remove a builder instance
  stop        Stop builder instance
  use         Set the current builder instance
  version     Show buildx version information

$ docker buildx  version
github.com/docker/buildx v0.2.0-32-g715d38f-tp 715d38ff9652eaac113ba1e12f6610c90b7cc223

Register Arm executables to run on x64 machines

Install the instruction emulation to register Arm executables to run on the x86 machine. For best results, the latest qemu should be used. If an older qemu is used some application may not work correctly on the x86 hardware.

$ docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3

The docker/binfmt has been updated with the latest qemu and replaces any previous instructions that call for linuxkit/binfmt:v0.7.

The project is available at github/docker/binfmt

To verify the qemu handlers are registered properly run:

$ cat /proc/sys/fs/binfmt_misc/qemu-aarch64
enabled
interpreter /usr/bin/qemu-aarch64
flags: OCF
offset 0
magic 7f454c460201010000000000000000000200b7
mask ffffffffffffff00fffffffffffffffffeffff

Make sure the first line of the output is “enabled”. Note that the handler registration doesn't survive a reboot, but can be added to the system start-up scripts.

Create a builder instance

Setup a new builder instance to create multi-architecture images.

$ docker buildx create --name mybuilder
$ docker buildx use mybuilder
$ docker buildx inspect --bootstrap

Try buildx

There are multiple examples of buildx available, but here is another simple one for C programmers! Create a file hello.c with this code:

#include <stdio.h>
#ifndef ARCH
#define ARCH "Undefined"
#endif
 
int main() {
  printf("Hello, my architecture is %s\n", ARCH);
  exit(0);
}

Here is a Dockerfile to build and run it. Let’s get used to using multi-stage Dockerfiles as it will be common for deploying embedded applications. Create a Dockerfile with this in it:

FROM alpine AS builder
RUN apk add build-base
WORKDIR /home
COPY hello.c .
RUN gcc "-DARCH=\"`uname -a`\"" hello.c -o hello
 
FROM alpine
WORKDIR /home
COPY --from=builder /home/hello .
ENTRYPOINT ["./hello"]

Now, use buildx to build for multiple architectures and push to Docker hub.

Use docker login first if needed and substitute your own Hub account instead of mine. The imagetools inspect command confirms that the image has support for the three architectures specified in the build command and prints the full image ID for each architecture.

$ docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 --push -t jasonrandrews/hello .
$ docker buildx imagetools inspect jasonrandrews/hello

Run using the sha from the manifest and see the output from uname as armv7l, aarch64, or x86_64:

$ docker run docker.io/jasonrandrews/hello:latest@sha256:07ef3789cfc140b02797a58868bc7140a3c0b9efce5100a7e57b19388257e2a4
Hello, my architecture is Linux buildkitsandbox 4.15.0-1039-aws #41-Ubuntu SMP Wed May 8 10:43:54 UTC 2019 aarch64 Linux

Next steps

Docker has been able to simplify enterprise software development and deployment. Support for Arm-based cloud instances delivers true multi-platform portability and cost savings. Even more exciting to me is how Docker is changing the way embedded software is being developed and deployed. There are many embedded systems running Linux today. For as long as I can remember software applications have been created by cross-compiling and copying files to an embedded target board. There are various tricks to automate this process, but it has generally been unchanged since the 1990’s when non-x86 embedded possessors running Linux appeared. Docker stands to make the first significant change to the embedded Linux application developer’s workflow.

As we have seen, multi-architecture containers can be created with buildx in the same way as with Docker Desktop for Mac and Windows. Give it a try for yourself and start making the transition to multi-architecture Docker images today.

Developer Tutorials

Anonymous
  • ABog
    ABog over 3 years ago

    I had some issues installing buildx (on Ubuntu):

    • "Download a binary release" --> seemed easy, but failed

    • "Download, build, and install buildx" --> build failed

    Docker Buildx | Docker Documentation had a note for Unix environments: 

    chmod a+x ~/.docker/cli-plugins/docker-buildx

    afterwards docker buildx --help works!

    • Cancel
    • Up 0 Down
    • Reply
    • More
    • Cancel
Tools, Software and IDEs blog
  • GCC 15: Continuously Improving

    Tamar Christina
    Tamar Christina
    GCC 15 brings major Arm optimizations: enhanced vectorization, FP8 support, Neoverse tuning, and 3–5% performance gains on SPEC CPU 2017.
    • June 26, 2025
  • GitHub and Arm are transforming development on Windows for developers

    Pareena Verma
    Pareena Verma
    Develop, test, and deploy natively on Windows on Arm with GitHub-hosted Arm runners—faster CI/CD, AI tooling, and full dev stack, no emulation needed.
    • May 20, 2025
  • What is new in LLVM 20?

    Volodymyr Turanskyy
    Volodymyr Turanskyy
    Discover what's new in LLVM 20, including Armv9.6-A support, SVE2.1 features, and key performance and code generation improvements.
    • April 29, 2025