174

Current beta version of docker requires you to specify a --platform=linux/amd64 each time you need to build or run an amd64 image/container.

The documentation mentions

When running an image with multi-architecture support, docker will automatically select an image variant which matches your OS and architecture.

The documentation does not specify a way to alter this automatic behaviour using env variables. It seems to ignore both BUILDPLATFORM and TARGETPLATFORM.

Is there any other way to force docker to run all build and run commands with a platform linux/amd64 instead of linux/arm64/v8 by default on macOS running on apple-silicon?

Vojtech Letal
  • 2,168
  • 3
  • 13
  • 17

7 Answers7

265

You can set the environment variable DOCKER_DEFAULT_PLATFORM:

export DOCKER_DEFAULT_PLATFORM=linux/amd64
Eduardo Cuomo
  • 17,828
  • 6
  • 117
  • 94
Beppe C
  • 11,256
  • 2
  • 19
  • 41
  • This was introduced in v19.03.0 in 03/2019. I do not understand how I missed that. – Vojtech Letal May 18 '21 at 18:19
  • 1
    This answer works but builds will be slow. Solution - https://blog.driftingruby.com/docker-builds/ – kctang Jun 20 '22 at 14:45
  • This is great and it works, but i've also found I need to _unset_ it when creating clusters with `kind`. If you get errors like `docker: Cannot overwrite digest sha256:...`, try unsetting the `DOCKER_DEFAULT_PLATFORM` var. – Max Cascone Jan 04 '23 at 17:39
  • 1
    is it possible to configure this option within a docker configuration file rather than a shell environment? – slai-nick Jan 12 '23 at 13:03
  • 1
    The link provided by @kctang is broken. Here is one that works: https://blog.driftingruby.com/articles/2022/04/09/docker-builds-are-slow-on-m1.html – jeffmcc Jun 17 '23 at 00:32
197

Docker images built with Apple Silicon (or another ARM64 based architecture) can create issues when deploying the images to a Linux or Windows based *AMD64 environment (e.g. AWS EC2, ECS, etc.). For example, you may try to upload your docker image made on the M1 chip to an AWS ECR repository and it fails to run. Therefore, you need a way to build AMD64 based images on the ARM64 architecture, whether it's using Docker build (for individual images) or docker-compose build (e.g. for multi-image apps running in a docker compose network).

For building single docker images: Set your environment variable using the command line or modifying your .bashrc or .zshenv file as suggested in the accepted answer.

export DOCKER_DEFAULT_PLATFORM=linux/amd64

Alternatively, in the Dockerfile, include the following flag in the FROM command (for a multi-stage Dockerfile build, the flag is only needed for the first stage):

FROM --platform=linux/amd64 python:3.7-alpine

For building images as part of a docker-compose build, include the platform: linux/amd64 for each service. For example:

  services:  
    frontend:  
      platform: linux/amd64
      build: frontend  
      ports:
        - 80:80  
      depends_on:
        - backend  
    backend:  
      platform: linux/amd64
      build: backend  
Eduardo Cuomo
  • 17,828
  • 6
  • 117
  • 94
WildGoose
  • 1,981
  • 1
  • 5
  • 4
  • What is the source of the "issues"? You mean like accidentally running ARM image on AMD64 platforms? Is it even possible? – Vojtech Letal Oct 22 '21 at 14:57
  • I prefer this solution (I'm using docker-compose) over the accepted answer of setting env variable on the host OS – Kim Stacks Dec 31 '21 at 16:00
  • 1
    This works great. I'm using docker-compose to build linux/amd64 applications on a M1 MacBook Pro. – dotslash Jan 18 '22 at 23:18
  • This is pretty old, but this points to the best option IMO, i chose to keep `platform` in `docker-compose.yaml` but adding `--platform=linux/amd64` do the `FROM` section of `DockerFile` seemed to be the best fix. – ekydfejj Mar 13 '22 at 21:25
  • 1
    I prefer putting this in the `docker-compose.yml` file as well. This saved me. Thanks a lot! – juntunen May 02 '22 at 03:42
  • will it work for docker-compose v3 files? – arxakoulini Jun 30 '23 at 13:18
44

You don't need to export the env variable as mentioned in one of the answers, you can run it as part of the command a single time by doing:

DOCKER_DEFAULT_PLATFORM=linux/amd64 docker-compose build

Keep in mind that if you've already downloaded the image for a different platform, docker will keep using that image no matter what platform you specify as your default, you would delete the image using docker image rm your_img first to fix that.

Eduardo Cuomo
  • 17,828
  • 6
  • 117
  • 94
Timo Huovinen
  • 53,325
  • 33
  • 152
  • 143
14

You can use buildx (mobi) which suipport cli for platform.

docker buildx build --platform linux/amd64 .
Eduardo Cuomo
  • 17,828
  • 6
  • 117
  • 94
Max Barrass
  • 2,776
  • 1
  • 19
  • 10
  • Here is my Debian ARM docker build https://github.com/aem-design/docker-tini/blob/debian-arm/build.ps1 and here is the pipeline https://github.com/aem-design/docker-tini/blob/debian-arm/.github/workflows/build.yml. Its used here https://github.com/aem-design/docker-oracle-jdk/blob/jdk8-arm/Dockerfile. – Max Barrass Mar 03 '22 at 09:56
  • Well buildx is an extra addition to docker hence ive mentioned it. But for Docker as is the docs on ENV variables are here https://docs.docker.com/engine/reference/commandline/cli/#environment-variables and they seem to be clear and to the point without any snark remarks. – Max Barrass Mar 03 '22 at 10:13
14

you can set

export DOCKER_DEFAULT_PLATFORM=linux/amd64

in a .zshrc file for Mac M1

6

You can add in your docker-compose.yaml:

services:
  service_name:
    environment:
      - DOCKER_DEFAULT_PLATFORM=linux/amd64
Eduardo Cuomo
  • 17,828
  • 6
  • 117
  • 94
ekimas
  • 393
  • 5
  • 10
1

Add this snipped to your ~/.zshrc and ~/.bashrc. It allows you not to repeat the flag anytime you perform a docker run command:

# useful only for Mac OS Silicon M1, 
# still working but useless for the other platforms
docker() {
  if [[ `uname -m` == "arm64" ]] && [[ "$1" == "run" || "$1" == "build" ]]; then
     /usr/local/bin/docker "$1" --platform linux/amd64 "${@:2}"
  else
     /usr/local/bin/docker "$@"
  fi
}
Alessandro Argentieri
  • 2,901
  • 3
  • 32
  • 62