Skip to content

Docker Fails When Building on M1 Macs (exec format error)

Problem Statement

Developers using Apple Silicon (M1/M2) Macs frequently encounter the error exec /usr/local/bin/docker-entrypoint.sh: exec format error when building or running Docker containers originally designed for x86-64 (AMD64) architecture. This occurs because Apple Silicon uses ARM64 architecture, creating compatibility issues with many Docker images that were built for traditional Intel-based systems.

The error typically manifests when:

  • Building Docker images that inherit from base images not optimized for ARM64
  • Running containers that contain x86-64 binaries on ARM64 architecture
  • Using legacy Docker configurations without platform specifications

Solution

The most effective solution is to explicitly specify the target platform when building or running containers on Apple Silicon Macs.

Specify Platform in Dockerfile

Modify your FROM instruction to explicitly target the AMD64 platform:

dockerfile
FROM --platform=linux/amd64 node:11.15

This ensures Docker pulls and uses the AMD64 version of the base image, maintaining compatibility with applications not yet optimized for ARM64.

Specify Platform During Build Command

Alternatively, you can specify the platform when building your Docker image:

bash
docker build --platform=linux/amd64 -t your-image:tag .

Platform Options

For different scenarios, you might need to specify different platforms:

dockerfile
# For traditional x86-64 compatibility
FROM --platform=linux/x86_64 node:20

# For native ARM64 performance (when available)
FROM --platform=linux/ARM64 node:20

Complete Fixed Dockerfile Example

Here's how your Dockerfile should look with the platform specification:

dockerfile
#nodejs - with explicit platform specification
FROM --platform=linux/amd64 node:11.15
ENV NODE_VERSION 11.15

#app directory
WORKDIR ./

#mongodb tools
RUN wget -qO - https://www.mongodb.org/static/pgp/server-5.0.asc | apt-key add -
RUN echo "deb http://repo.mongodb.org/apt/debian buster/mongodb-org/5.0 main" | tee /etc/apt/sources.list.d/mongodb-org-5.0.list
RUN apt-get update
RUN apt-get install -y mongodb

RUN apt-get install nano

#nodejs packages
COPY package*.json ./

RUN npm install --ignore-scripts sharp
RUN npm install --only=production

COPY . .

RUN mkdir -p /logs/

# wait for mongoDB launch
ADD https://github.com/ufoscout/docker-compose-wait/releases/download/2.5.1/wait /wait
RUN chmod +x /wait

#port of the app
EXPOSE 8080

CMD /wait && npm run dockerServer

Explanation

Why This Happens

Apple Silicon Macs use ARM64 architecture, while most legacy Docker images were built for x86-64 architecture. When Docker tries to execute binaries compiled for a different architecture, it results in the "exec format error" because the CPU cannot interpret the machine code instructions.

Performance Consideration

While using --platform=linux/amd64 ensures compatibility, it runs through emulation (Rosetta 2) which may have performance implications. For better performance, consider:

  • Finding ARM64-native versions of your base images
  • Rebuilding your application and dependencies for ARM64
  • Using multi-architecture images when available

Long-term Solution

The platform specification is a compatibility workaround. For production applications, consider creating multi-architecture images that support both AMD64 and ARM64:

dockerfile
# Example of multi-stage build for multiple architectures
FROM --platform=$BUILDPLATFORM node:20 AS build
# ... build steps

FROM node:20
COPY --from=build /app /app

Additional Considerations

  1. Docker Compose Compatibility: When using Docker Compose, you can also specify the platform:
yaml
services:
  your-service:
    platform: linux/amd64
    image: your-image
  1. Check Image Architecture: Use docker inspect <image> to check the architecture of existing images.

  2. Buildx for Multi-arch: For production deployment, consider using docker buildx to create images that work across multiple architectures.

This solution resolves the immediate compatibility issue while providing a path toward proper multi-architecture support for your Docker containers.