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