Your Mac M 1 Docker Image Will Not Work On Production: Here’s Why.
Here is the reason and how to fix it once and for all!
I’ve been using Ubuntu for a while. As a Linux distribution user using an Intel chip, building a docker image and pushing it on dockerhub for production (through a docker-compose file or on Kubernetes) is not a big deal.
But I got the new Macbook Pro M1 a few weeks ago. I had to install the same dev tools and get working on my projects as usual.
Everything worked pretty well on my local till I got to the point where I needed to make my docker image work on Kubernetes.
I first pushed the image build on my M1 to dockerhub. But my deployments were failing to create the pods on Elastic Kubernetes Service (AWS EKS).
What’s Going On Actually
After a few checks, I found out that my docker image was built upon the arm architecture.
M1 chips are ARM-based. As we know, docker builds images based on the underneath architecture on which it is installed. So:
- If you’re running Docker on an AMD architecture SoC, your images will be built for AMD architectures,
- If you’re rather running docker on ARM chips then your images will be ARM-based.
Most of the online servers are AMD-based these days.
So your native docker image built on your Mac M1 is not going to work on most of the online servers.
Now, the question is: How To Fix It?
Very simple. We have to tell docker that we’re building the image for AMD architecture. What it means is that this image will only be used on AMD architecture platforms.
Let’s try it out. Head up over to your workspace folder where your Dockerfile is set and run the following command.
docker buildx build --platform linux/amd64
-t <your-dockerhub-username>/<your-image-name> \
-f Dockerfile \
Let’s break down what we’re doing here.
- buildx build: It’s a CLI plugin meant for building for multiple platforms and not only for the architecture and operating system that the user invoking the build happens to run. The
docker buildx buildcommand supports features available for
docker build, including features such as outputs configuration, inline build caching, and specifying target platform.
- — platform linux/amd64: Here we’re specifying to
docker buildxthe target platform we’d like to build the docker image for,
- -t: It’s an option to tag our image and you should be used to it,
- -f: it’s the name or the path to our Dockerfile (can be Dockerfile.dev, Dockerfile.prod based on the name you gave to it),
- — push: It’s an option to specify to docker that we want to push the image on dockerhub once it’s built,
- — no-cache: this option tells docker to get rid of any cached data about this image.
After you run that, Docker will build the image and push it to your dockerhub.com account and you’ll be able to use it on most of the online servers.
One may be tempted to say that the Docker concept is a scam at the end of the day because we need to build an image for every platform. It’s not. We can see that Docker’s team is striving to provide the best experience for all of its users. Even if there are some important improvements to make, Docker is a great tool that changes the way we create, develop, and ship apps.
Thanks for reading. Kudos to the Docker team for the work it’s doing.
Till next time, take care!