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 errorError 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/amd64for production builds - Don't copy node_modules between Docker stages
- Run
npm ci --production && npm rebuildin 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
Immediate: Rebuild with correct architecture
docker buildx build --platform linux/amd64 -t image:fix --push .Redeploy: Trigger deployment with new image
Verify: Check health endpoint confirms x64 architecture
If Can't Rebuild Immediately
- Rollback: Deploy last known working version
- Use CI/CD: GitHub Actions runs on AMD64 by default
- 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
- Always specify
--platform linux/amd64for production builds - Never copy node_modules between Docker build stages
- Install production dependencies fresh in the final stage
- Test on target architecture before deployment
- "exec format error" = architecture mismatch, not permissions