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

270 lines
7.4 KiB
Markdown

# 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).