# 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 ```bash ./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 ```bash ./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 ```bash ./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 ```bash 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 ```bash 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: ```bash docker login gitea-http.taildb3494.ts.net:3000 ``` ## Platform-Specific Deployment ### AMD64 (Development/Standard Servers) ```bash # 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) ```bash # 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 ```bash # 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: ```yaml 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: ```yaml 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 ```bash # 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 ```yaml 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).