"exec format error" when running containers build with Apple M1 Chip (ARM based systems)

Viewed 7925

Expected behavior: I can run a container I've built using an Apple M1 chip.

Observed behavior:

Assuming you have a Google Cloud Run account and can push Docker images to Google Container Registry. I'm using https://github.com/seenickcode/trivial-go-api for this example.

  1. `git clone git@github.com:seenickcode/trivial-go-api.git'
  2. cd trivial-go-api
  3. docker build -t gcr.io/<YOUR GCR PROJECT ID>/example .
  4. docker push -t gcr.io/<YOUR GCR PROJECT ID>/example
  5. Go to console.cloud.google.com, Google Cloud Run > Create new service > select your pushed Docker image with all default options > Run
  6. Error shown:
Cloud Run error: Container failed to start. 
Failed to start and then listen on the port defined by the PORT environment variable. 
Logs for this revision might contain more information.

Logs:

2021-04-02 09:35:40.045 EDT
Cloud Run ReplaceService example hello@redactedforso.com {@type: type.googleapis.com/google.cloud.audit.AuditLog, authenticationInfo: {…}, authorizationInfo: […], methodName: google.cloud.run.v1.Services.ReplaceService, request: {…}, requestMetadata: {…}, resourceLocation: {…}, resourceName: namespaces/myprojectforso-282419/services/example, response: {…}, servi…
Error
2021-04-02 09:35:49.034 EDT
terminated: Application failed to start: Failed to create init process: failed to load /app/main: exec format error
Warning
2021-04-02 09:35:49.174 EDT
Application exec likely failed
Notice
2021-04-02 09:57:43.102 EDT
Cloud Run ReplaceService example hello@redactedforso.com {@type: type.googleapis.com/google.cloud.audit.AuditLog, authenticationInfo: {…}, authorizationInfo: […], methodName: google.cloud.run.v1.Services.ReplaceService, request: {…}, requestMetadata: {…}, resourceLocation: {…}, resourceName: namespaces/myprojectforso-282419/services/example, response: {…}, servi…
Error
2021-04-02 09:57:50.657 EDT
terminated: Application failed to start: Failed to create init process: failed to load /app/main: exec format error

System details on where I'm building my image:

  • OS: macOS 11.2.3
  • Chip: Apple M1
  • Docker version: Docker Desktop for macOS v3.3.0 (62345)

Important Notes:

  • This all works completely fine for me when I use another architecture, i.e. via Google Container Build or my home Windows (WSL) desktop.
  • This also doesn't work with other codebases when built using the Apple M1 Chip, such as another project I have written in Rust as well as Dart. Doesn't seem language related.
  • I've been using Google Cloud Run for years, this issue cropped up when using my new laptop with Apple M1 Chip.
3 Answers

You are building an ARM-compatible image which Google Cloud does not support.

I have hit a similar problem pushing my Mac M1 built image to Heroku, which I solved using buildx and setting the expected platform

docker buildx build --platform linux/amd64 -t myapp .

I have written a Medium post to explain the problem and propose 2 solutions.

Docker is by design multi-platform and can run on different architectures, however, the images must match the platform they will be run on. Which is not our case.

Also you can build x86 compatible image and push to artifact registry with single command:

docker buildx build \
--platform linux/amd64 \
--push \
-t us-central1-docker.pkg.dev/your_project/your_registry/myapp .

As from docker API version 1.40, you can specify the platform upon which your image needs to be built by using the --platform option, without using buildx.

docker build --platform=linux/amd64 -t myapp .
Related