Build X86-64 Docker images on M1 for AWS ECR

In a recent project I needed to build an X86-64 (AMD64) Docker image and push it to AWS Elastic Container Registry (ECR). The problem was that I use a Mac with an M1 chip. This led to an error when I was trying to run the ECS Task, since the rest of the infrastructure is built on AMD64. Luckily, I was able to figure out a way to build this image for an AMD64 architecture and get it deployed to AWS. Here’s how I did it using Docker Buildx.

Docker Buildx

If you’re bothering to read this, I’m sure you’ve ran the docker build command before. Docker buildx is a very similar command which allows you to build cross-architecture images. It provisions a Moby BuildKit container which is what provides the additional functionality. But how do you use it?

Enabling buildx

Before we get started we’ll need to enable the docker buildx command. If you use Docker Desktop you can enable this by going to settings -> Features in development -> Experimental Features and click the Access experimental features checkbox. Then click Apply & restart. If you don’t use Docker Desktop there are plenty of instructions out there on how to install it for your system. Once you have it installed, if you type docker buildx in the terminal it should spit out a bunch of information about the command. The first command we’re going to look at is create.

Building the image

To spin up our BuildKit container we’re going to run docker buildx create. You can optionally pass the --name option if you want, but it’ll probably be the only moby/buildkit image you’ll be running anyway. This is going to spin up the container we’re going to use to build our image.

Next, we can build the image. Since we’re pushing to an ECR repository we’ll click the View push commands button and grab the command from step 2 (more instructions on this below if you don’t know what I’m talking about). The AWS ECR build command should look something like this: docker build -t repository-name .

We’re going to edit this command a bit to make sure we build the image for the correct architecture.

docker buildx build --platform linux/amd64 -t repository-name --load .

The repository-name should be whatever the ECR push commands tells you to use. The --load option will instruct Docker Buildx to load the newly built image to your local Docker daemon automatically. This makes it available for you to continue using the ECR push commands as you normally would in order to push the image to your repository.

Pushing to ECR

I’m assuming most people reading this will already be familiar with pushing to ECR and won’t need any instruction on it. However, if you’re not familiar, getting the instructions to push your image to your ECR repository is very easy. Log into your AWS account and search for ECR. If you don’t already have a repository, create one and give it a name. Then when you go into that repository, you will see a “view push commands” button. A window will pop up giving you the information and the commands you need in order to be able to push your image. Keep in mind that you’ll need the AWS CLI set up on your system. The pop up window provides a link to instructions on how to do this.

In Closing

I’ll note that, in my search on trying to solve this problem, I came across a few tutorials that instructed me to use the --push flag to push the image directly to my ECR repository. However, this didn’t work for me. I couldn’t get the Docker Buildx container to authenticate with ECR. That is why I instead used the --load flag which allowed me to push the image manually.

Well, I hope this helps! And if you are interested in learning more about AWS, Docker, or Full Stack Web Development in general, be sure to check out my other posts here.