Engineering

    ARM64 Docker builds: the seven errors everyone hits first

    Ampere A1 instances are the reason Oracle's free tier is worth using — and ARM64 is the reason the first deploy fails. Every error below has a one-line fix.

    Published 2026-08-11 · 9 min read

    1. exec format error

    The image was built for amd64 and the host is arm64. Nothing inside the container will ever start.

    Build on the ARM machine itself, or cross-build explicitly:

    docker build --platform linux/arm64 -t myapp .
    # or, for both architectures
    docker buildx build --platform linux/amd64,linux/arm64 -t myapp --push .

    2. Painfully slow builds under emulation

    Building arm64 images on an x86 laptop uses QEMU emulation, which can be five to twenty times slower. Building on the Oracle VM instead is usually faster than emulating locally — which is exactly why Cheaploy builds on your instance.

    3. No prebuilt Python wheel

    Most major packages now ship aarch64 wheels. When one does not, pip falls back to compiling from source and fails on a missing toolchain. Install the build dependencies, or pick a slim variant with them available:

    RUN apt-get update && apt-get install -y --no-install-recommends \
          build-essential python3-dev libffi-dev \
     && rm -rf /var/lib/apt/lists/*

    4. Node native modules

    bcrypt, sharp, canvas and better-sqlite3 compile native code. On Alpine ARM64 they need build-base plus the relevant -dev packages; on Debian slim they usually just work.

    Where possible, prefer pure-JS alternatives (bcryptjs) or the platform-specific optional dependencies published by the maintainers.

    RUN apk add --no-cache build-base python3 vips-dev

    5. Base images without an arm64 tag

    Some smaller community images are amd64 only. Check before you commit to one:

    docker manifest inspect <image> | grep architecture

    6. Out of memory during the build

    Webpack, Turbopack, Vite and the Strapi admin build all spike memory. Give the build 4 GB or more, and never run it on the 1 GB AMD micro instance. Raising Node's heap helps on tight shapes:

    ENV NODE_OPTIONS=--max-old-space-size=3072

    7. Images that are far bigger than they need to be

    Multi-stage builds matter more on a home connection than on a datacentre network. A Go binary in distroless is ~15 MB; a naive Node image is often 1.2 GB. Copy only build output into the final stage, use .dockerignore, and pin base image versions.

    # .dockerignore
    node_modules
    .git
    .env*
    dist
    coverage

    Skip all of this

    The free Dockerfile generator writes an ARM-ready multi-stage Dockerfile for your stack, and Cheaploy builds it on the instance so the architecture always matches.

    Keep reading

    Get the Oracle Always Free deploy checklist

    One email with the exact steps, capacity workarounds and tools we use to ship apps for $0 of cloud spend.

    One email, no spam. Unsubscribe anytime.

    Frequently asked

    Is ARM slower than x86?+

    For typical web workloads, no. An Ampere A1 OCPU is a dedicated physical core and generally outperforms a shared x86 vCPU on entry-level plans.

    Does everything run on ARM now?+

    Almost everything mainstream does. The exceptions are closed-source amd64-only binaries and some older database images.

    Can I mix architectures?+

    Yes, with multi-arch manifests, but it is simpler to standardise on arm64 for Oracle.

    Deploy your project for $0

    No credit card. No Oracle sales call. Ship to your own cloud in under 10 minutes.

    Start free