Building ARM-based container images with VSTS for your Azure IoT Edge deployments

Currently, I am working and playing around with Azure IoT Edge deployments in combination with Azure Kubernetes Service and a Raspberry Pi 2.

The files referenced in through out the blog article can be found in my GitHub repository.


My first challenge was to find a way on how to build ARM-based container images in a CI/CD pipeline using VSTS. VSTS offers hosted agents for builds and releases, but they are only x64 based. Alright, I thought, maybe there is an ARM-based VSTS agent for download available. However, the bits are also only available for the x64 platform. So, using the Raspberry Pi 2 for the build and release processes with the VSTS agent felt out as the second option.

After those disappointing results I went back to do some research on the Internet. Finally, I found a blog article mentioning and describing the use of QEMU for emulation, enabling the build of ARM-based container images on the x64 platform.


As described in the referenced blog article we need the qemu-arm-static file to be included in the ARM-based container images. First step is installing QEMU on a Linux VM, e.g. Ubuntu, with the following commands.

sudo apt update
sudo apt install -y qemu qemu-user-static qemu-user binfmt-support

Then we can copy it from the Linux VM (/usr/bin folder) into our code repository and start building the Dockerfile.

FROM arm32v7/ubuntu:18.04
LABEL Daniel Neumann <>
COPY qemu-arm-static /usr/bin/qemu-arm-static
ENV VERSION=1.10.2 \
  OS=linux \
RUN apt-get update \
  && apt-get install -y wget \
  && apt-get install -y gcc \
  && rm -rf /var/lib/apt/lists/* \
  && wget $GO_DL \
  && tar -C /usr/local -xzf go$VERSION.$OS-$ARCH.tar.gz \
  && rm go$VERSION.$OS-$ARCH.tar.gz
ENV PATH=/usr/local/go/bin:$PATH
WORKDIR /webapp
ADD /go-webapp .
RUN go build .

The most important part in the Dockerfile is the COPY statement for the qemu-arm-static file into the /usr/bin folder. That enables the build of the ARM-based container image on the hosted Linux VSTS agent. Next step is the definition of the build process and here we must keep an important build task in mind. Otherwise we will face a permission issue during the build.

Add a shell script task and link it to the file in the code repository.


chmod 777 /opt/vsts/work/1/s/go-webapp-arm/qemu-arm-static

Replace go-webapp-arm with the name of your folder. E.g. see screenshot.


The next task is for the build agent preparation. Here we need to select as task “Run a Docker command” and add the following command under “Command”.

run --rm --privileged multiarch/qemu-user-static:register --reset


This ensures that our build agent can build an ARM-based container image using QEMU for emulation.

The next two build tasks are specifying the build and the push of the container image to the Azure Container Registry. Details can be found in the following screenshots and a quick start guide under the following link.



Now, we can click on “Save & queue” to initialize the build process. If everything went successful, we should see a green build process and the ARM-based container image in the Azure Container Registry.


As you can see it is simple to build ARM-based container images with VSTS, when using QEMU for emulation. One of the next blog articles will be about deploying the ARM-based container image on an Azure IoT Edge device via the Virtual Kubelet IoT Edge Provider for Azure Kubernetes Service. Stay tuned.