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:
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:
docker build --platform=linux/amd64 -t your-image:tag .
Platform Options
For different scenarios, you might need to specify different platforms:
# 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:
#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:
# 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
- Docker Compose Compatibility: When using Docker Compose, you can also specify the platform:
services:
your-service:
platform: linux/amd64
image: your-image
Check Image Architecture: Use
docker inspect <image>
to check the architecture of existing images.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.