Last updated: Aug 12, 2025, 01:09 PM UTC

Docker Architecture Troubleshooting Guide

Problem: Docker Images Fail with "exec format error" on Deployment

Quick Diagnosis

If you see errors like:

  • exec /usr/bin/dumb-init: exec format error
  • Error loading shared library .../node-pty/build/Release/pty.node: Exec format error

You have an architecture mismatch: Your Docker image was built for the wrong CPU architecture.

Common Scenario

  • Development Machine: Apple Silicon Mac (M1/M2/M3) - ARM64/aarch64 architecture
  • Production Server: Sliplane, AWS, most cloud providers - AMD64/x86_64 architecture
  • Result: Images built on Mac fail on production servers

Solution: Build for the Target Architecture

1. Always Build for AMD64 for Production

# βœ… CORRECT - Explicitly target AMD64
docker buildx build \
  --platform linux/amd64 \
  -f Dockerfile \
  -t your-image:tag \
  --push \
  .

# ❌ WRONG - Uses your machine's architecture
docker build -t your-image:tag .

2. Fix Native Node.js Modules

Native modules (node-pty, bcrypt, better-sqlite3) must be compiled for the target architecture.

Wrong Approach - Copying node_modules

# This copies ARM64 binaries to AMD64 container!
FROM node:20-alpine AS builder
RUN npm ci
RUN npm run build

FROM node:20-alpine AS runner
COPY --from=builder /app/node_modules ./node_modules  # ❌ Architecture mismatch!

Correct Approach - Fresh Install in Runner

FROM node:20-alpine AS builder
RUN npm ci
RUN npm run build
RUN rm -rf node_modules  # Remove to prevent contamination

FROM node:20-alpine AS runner
COPY --from=builder /app/dist ./dist
COPY package*.json ./
# Install fresh for correct architecture
RUN npm ci --production && npm rebuild

Verification Steps

1. Check Your Built Image Architecture

# Should show "amd64" for production deployments
docker image inspect your-image:tag | grep Architecture

2. Test Inside Container

# Should output "x86_64" for AMD64
docker run --rm your-image:tag uname -m

3. Verify in Health Endpoint

Add architecture info to your health check:

app.get('/api/health', (req, res) => {
  res.json({
    build: {
      platform: process.platform,
      arch: process.arch  // Should be "x64" for AMD64
    }
  });
});

Common Native Modules That Cause Issues

Module Purpose Solution
node-pty Terminal emulation Must rebuild for target arch
bcrypt Password hashing Consider bcryptjs (pure JS)
better-sqlite3 SQLite database Must rebuild for target arch
sharp Image processing Must rebuild for target arch
canvas Canvas rendering Must rebuild for target arch

Prevention Checklist

  • Use docker buildx build --platform linux/amd64 for production builds
  • Don't copy node_modules between Docker stages
  • Run npm ci --production && npm rebuild in final stage
  • Test on actual deployment platform before release
  • Add architecture info to health endpoints
  • Document build requirements in README

Emergency Fixes

If Already Deployed Wrong Architecture

  1. Immediate: Rebuild with correct architecture

    docker buildx build --platform linux/amd64 -t image:fix --push .
    
  2. Redeploy: Trigger deployment with new image

  3. Verify: Check health endpoint confirms x64 architecture

If Can't Rebuild Immediately

  1. Rollback: Deploy last known working version
  2. Use CI/CD: GitHub Actions runs on AMD64 by default
  3. Remote Build: Use a Linux/AMD64 machine for builds

Platform-Specific Build Script

Create a build-production.sh:

#!/bin/bash
set -e

VERSION=$(cat VERSION)

echo "Building AMD64 image for production..."
docker buildx build \
  --platform linux/amd64 \
  -f Dockerfile.production \
  -t myapp:$VERSION \
  -t myapp:latest \
  --push \
  .

echo "βœ… AMD64 image pushed: myapp:$VERSION"

Debugging Commands

# Check what architecture Docker is building for
docker buildx ls

# Inspect a running container
docker exec container-name uname -m
docker exec container-name node -p "process.arch"

# Check specific binary architecture
docker run --rm your-image file /usr/bin/dumb-init
docker run --rm your-image file /app/node_modules/node-pty/build/Release/pty.node

Key Takeaways

  1. Always specify --platform linux/amd64 for production builds
  2. Never copy node_modules between Docker build stages
  3. Install production dependencies fresh in the final stage
  4. Test on target architecture before deployment
  5. "exec format error" = architecture mismatch, not permissions

Related Documentation