Bitbucket Pipelines, Docker and the Apple M1 chip

Gepubliceerd op:

Tags: deployment | docker | english | webdevelopment

(Photo by Quinten de Graaf on Unsplash)

TL;DR: Docker images built on a Mac with a M1 processor produce images with ARM architecture. Now that also means that they don’t work on Bitbucket pipelines. Why? Because Bitbucket does not support ARM builds.

Since some time the pipelines at Bitbucket were failing without any error message. These pipelines were not crucial, so it took me some time to get around fixing them. Originally I had planned an hour on Friday to dive into the problem and fix it. In the end, it took me more than a day to realize why the pipelines were failing. And I’m ashamed to admit that, looking back on it, it was a very simple mistake.

Now, to give myself an excuse as to why it took me so long to figure out: there was no error message at all. I received an e-mail saying “Pipeline for master failed on <some commit hash>” and that’s that. So naturally, I considered a wide array of possible options of what could be going wrong. Starting with the more rational explanations, but slowly descending into madness as I could not figure out what was going wrong.

Maybe it has something to do with the image itself?
Well yes maybe, but it does run perfectly on my machine. Also, it seems to fail before running the image itself. Even when the Dockerfile only contains FROM php:7.4-fpm it keeps on failing.

Maybe Bitbucket can’t access my (publicly available!) images.
Nope. I triple checked the repository settings and tried pulling the image without beging logged-on to the Docker hub. Worked fine.

Maybe it’s DNS?
Because it’s always DNS. But alas, this time it was not.

Maybe Zalgo has come to devour our world?
No (X)HTML or Regexes were in sight, so I guess not.

As I was slowly losing my mind (the following Monday, by the way), I noticed a little tag alongside my Docker image:

“arm64? What? No, that can’t be right…”. And it wasn’t right, because that set me on the right course to fix the issue. Basically, the images were built on a Mac machine with a M1 processor. Because of this the images were built for ARM processors. But the machines over at Bitbucket cannot handle this and require images built for x86/AMD64.

How to make Docker images built on a M1 chip work on Bitbucket pipelines?

Luckily, the answer comes in the form of a relatively new* docker command: buildx. This command is included by default in Docker Desktop for MacOS. It adds features provided by BuildKit in a single command. From the documentation:

BuildKit is designed to work well for building for multiple platforms and not only for the architecture and operating system that the user invoking the build happens to run.

* I’m just saying that to make myself feel better

With buildx we can specify the target platform/architecture for our image. This means the docker image that is created has a different architecture than the platform it is built upon (ARM). Exactly what is needed to make the image run on Bitbucket Pipelines.

In short, use the following command to build your image for x86/AMD64. As can be seen from the command, the platform that’s being targeted is specified in the command: --platform linux/amd64.

docker buildx build --push --platform linux/amd64 --tag username/image-name:latest .

With this this image is built for x86/AMD64 and should work fine. I’m just a little bit annoyed it took me so long to figure it out 😄.