Files
adopt-a-street/MULTIARCH_DOCKER.md
William Valentin 9f650fa7d4 feat: add multi-architecture Docker build setup
- Add Docker BuildKit builder setup for AMD64 and ARM64 platforms
- Update backend and frontend Dockerfiles with platform flags
- Create comprehensive build scripts for multi-arch workflows
- Add verification script to test multi-architecture images
- Update Makefile with multi-arch Docker targets
- Add detailed documentation for multi-architecture setup

This enables building Docker images that work on both development machines
(AMD64) and Raspberry Pi cluster (ARM64) with automatic platform selection.

🤖 Generated with [AI Assistant]

Co-Authored-By: AI Assistant <noreply@ai-assistant.com>
2025-11-02 01:39:10 -08:00

7.4 KiB

Multi-Architecture Docker Setup

This document describes the multi-architecture Docker build setup for Adopt-a-Street, supporting both AMD64 (x86_64) and ARM64 (aarch64) platforms.

Overview

The multi-architecture setup enables:

  • Building Docker images that work on both development machines (AMD64) and Raspberry Pi cluster (ARM64)
  • Single image repository with platform-specific variants
  • Automatic platform selection when pulling images
  • Optimized builds for each target architecture

Architecture Support

Target Platforms

  • linux/amd64: Standard x86_64 servers and development machines
  • linux/arm64: ARM64 servers, Raspberry Pi 4/5, and other ARM64 devices

Base Images

  • Backend: oven/bun:1-alpine - Multi-architecture Bun runtime
  • Frontend: nginx:alpine - Multi-architecture Nginx web server

Build Scripts

1. Setup Multi-Architecture Builder

./scripts/setup-multiarch-builder.sh

This script:

  • Creates a Docker BuildKit builder named multiarch-builder
  • Configures it for multi-platform builds
  • Verifies platform support

2. Build and Push Multi-Architecture Images

./scripts/build-multiarch.sh [version]

Parameters:

  • version: Image version tag (defaults to latest)

This script:

  • Sets up the multi-architecture builder
  • Builds both backend and frontend images for AMD64 and ARM64
  • Pushes images to the registry with proper manifest lists
  • Tags images with both version and latest tags

3. Verify Multi-Architecture Images

./scripts/verify-multiarch.sh [version]

This script:

  • Inspects image manifests to verify multi-architecture support
  • Tests pulling images on the current platform
  • Validates that containers can start successfully

Manual Build Commands

Backend Multi-Architecture Build

docker buildx build \
  --platform linux/amd64,linux/arm64 \
  -t gitea-http.taildb3494.ts.net:3000/will/adopt-a-street/backend:latest \
  --push \
  backend/

Frontend Multi-Architecture Build

docker buildx build \
  --platform linux/amd64,linux/arm64 \
  -t gitea-http.taildb3494.ts.net:3000/will/adopt-a-street/frontend:latest \
  --push \
  frontend/

Dockerfile Optimizations

Backend Dockerfile

The backend Dockerfile uses:

  • --platform=$BUILDPLATFORM for the builder stage
  • --platform=$TARGETPLATFORM for the production stage
  • Multi-stage builds to reduce final image size
  • Alpine Linux base for minimal footprint

Frontend Dockerfile

The frontend Dockerfile uses:

  • --platform=$BUILDPLATFORM for the builder stage
  • --platform=$TARGETPLATFORM for the Nginx stage
  • Multi-stage builds with Bun for building and Nginx for serving
  • Static asset optimization

Registry Configuration

Image Repository

  • Registry: gitea-http.taildb3494.ts.net:3000/will/adopt-a-street
  • Backend: gitea-http.taildb3494.ts.net:3000/will/adopt-a-street/backend
  • Frontend: gitea-http.taildb3494.ts.net:3000/will/adopt-a-street/frontend

Authentication

Before building or pushing, authenticate with the registry:

docker login gitea-http.taildb3494.ts.net:3000

Platform-Specific Deployment

AMD64 (Development/Standard Servers)

# Pull images (automatically selects AMD64 variant)
docker pull gitea-http.taildb3494.ts.net:3000/will/adopt-a-street/backend:latest
docker pull gitea-http.taildb3494.ts.net:3000/will/adopt-a-street/frontend:latest

# Run containers
docker run -d -p 5000:5000 gitea-http.taildb3494.ts.net:3000/will/adopt-a-street/backend:latest
docker run -d -p 80:80 gitea-http.taildb3494.ts.net:3000/will/adopt-a-street/frontend:latest

ARM64 (Raspberry Pi Cluster)

# Pull images (automatically selects ARM64 variant)
docker pull gitea-http.taildb3494.ts.net:3000/will/adopt-a-street/backend:latest
docker pull gitea-http.taildb3494.ts.net:3000/will/adopt-a-street/frontend:latest

# Run containers
docker run -d -p 5000:5000 gitea-http.taildb3494.ts.net:3000/will/adopt-a-street/backend:latest
docker run -d -p 80:80 gitea-http.taildb3494.ts.net:3000/will/adopt-a-street/frontend:latest

Explicit Platform Selection

# Force specific platform
docker pull --platform linux/amd64 gitea-http.taildb3494.ts.net:3000/will/adopt-a-street/backend:latest
docker pull --platform linux/arm64 gitea-http.taildb3494.ts.net:3000/will/adopt-a-street/backend:latest

Kubernetes Deployment

Image Specifications

For Kubernetes manifests, use the same image names:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend
spec:
  template:
    spec:
      containers:
      - name: backend
        image: gitea-http.taildb3494.ts.net:3000/will/adopt-a-street/backend:latest
        # Kubernetes will automatically pull the correct architecture

Node Affinity (Optional)

For explicit node placement:

spec:
  template:
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: kubernetes.io/arch
                operator: In
                values: ["amd64"]
      containers:
      - name: backend
        image: gitea-http.taildb3494.ts.net:3000/will/adopt-a-street/backend:latest

Troubleshooting

Common Issues

  1. Builder not found: Run ./scripts/setup-multiarch-builder.sh
  2. Platform not supported: Ensure Docker BuildKit is enabled
  3. Push failures: Check registry authentication
  4. Emulation timeouts: Use native hardware for testing when possible

Debug Commands

# Check builder status
docker buildx ls

# Inspect image manifest
docker buildx imagetools inspect gitea-http.taildb3494.ts.net:3000/will/adopt-a-street/backend:latest

# Check platform support
docker buildx inspect --bootstrap

Performance Considerations

Build Time

  • Multi-architecture builds take longer than single-architecture builds
  • Consider building only needed platforms for development
  • Use build caching to speed up subsequent builds

Image Size

  • Alpine Linux base images keep sizes small (~50MB for backend, ~30MB for frontend)
  • Multi-stage builds reduce final image size
  • Platform-specific optimizations in base images

Runtime Performance

  • Native execution on each platform (no emulation)
  • Optimized binaries for each architecture
  • Consistent performance across platforms

Best Practices

  1. Always test on target platforms before deploying to production
  2. Use semantic versioning for image tags
  3. Keep base images updated for security patches
  4. Monitor build times and optimize build cache usage
  5. Document platform-specific requirements in deployment guides

CI/CD Integration

GitHub Actions Example

name: Build Multi-Architecture Images

on:
  push:
    tags: ['v*']

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    
    - name: Set up Docker Buildx
      uses: docker/setup-buildx-action@v2
    
    - name: Login to Registry
      uses: docker/login-action@v2
      with:
        registry: gitea-http.taildb3494.ts.net:3000
        username: ${{ secrets.REGISTRY_USERNAME }}
        password: ${{ secrets.REGISTRY_PASSWORD }}
    
    - name: Build and push
      run: ./scripts/build-multiarch.sh ${{ github.ref_name }}

This setup ensures that your Adopt-a-Street application can run seamlessly on both development infrastructure (AMD64) and production Raspberry Pi cluster (ARM64).