diff --git a/DEPLOY.md b/DEPLOY.md index ca5e3cb..e78a502 100644 --- a/DEPLOY.md +++ b/DEPLOY.md @@ -43,22 +43,44 @@ openssl rand -base64 32 See `.env.production.example` for full list with `[REQUIRED]` / `[FEATURE]` / `[OPTIONAL]` tags. -## Step 2: Build & Push Image +## Step 2: Build & Push Images + +Three images ship: `broker`, `web`, `migrate`. Use the multi-arch build script — +it produces both `linux/amd64` (VPS) and `linux/arm64` (Apple Silicon devs) +manifests so nobody hits QEMU emulation at runtime. ```bash -# Login to your registry (adjust for your setup) +# Login to your registry docker login -u -# Build for AMD64 (required for most VPS) -docker build --platform linux/amd64 \ - --build-arg NEXT_PUBLIC_URL=https://your-app.example.com \ - -t //:latest . +# Multi-arch build + push (all 3 images: broker, web, migrate) +scripts/build-multiarch.sh / -# Push -docker push //:latest +# Examples: +scripts/build-multiarch.sh # → ghcr.io/claudemesh/*: +scripts/build-multiarch.sh ghcr.io/myorg latest # → ghcr.io/myorg/*:latest +scripts/build-multiarch.sh localhost:5000/claudemesh 0.1.0 # → local registry ``` -Build takes ~2 min on Mac M-series. If push fails with EOF, retry. +The script tags each image with both `` and `:latest`. Builds in ~5-8 min +on Mac M-series (arm64 native is fast, amd64 via emulation is the slow leg). + +> **Mac Docker Desktop note**: if amd64 builds fail with `Input/output error` +> during `apt-get install`, enable **Settings → General → Use Rosetta for x86/amd64 +> emulation** (not QEMU). QEMU has known I/O stability issues on macOS; Rosetta +> is rock-solid. Linux CI runners don't hit this. + +### Single-arch fallback (if you really only need amd64) + +```bash +docker build --platform linux/amd64 \ + --build-arg NEXT_PUBLIC_URL=https://your-app.example.com \ + -f apps/web/Dockerfile \ + -t //web:latest . +docker push //web:latest +``` + +Repeat for `apps/broker/Dockerfile` and `packages/db/Dockerfile`. ## Step 3: Create Coolify Service diff --git a/scripts/build-and-push.sh b/scripts/build-and-push.sh deleted file mode 100755 index 05d67f6..0000000 --- a/scripts/build-and-push.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash -# Build Docker image locally and push to Gitea Container Registry -# Usage: ./scripts/build-and-push.sh [tag] - -set -e - -# Configuration -REGISTRY="192.168.1.3:3030" -REPO="alezmad/turbostarter" -TAG="${1:-latest}" -IMAGE="${REGISTRY}/${REPO}:${TAG}" - -echo "🔨 Building Docker image: ${IMAGE}" -docker build --platform linux/amd64 -t "${IMAGE}" . - -echo "📤 Pushing to Gitea registry..." -docker push "${IMAGE}" - -echo "✅ Done! Image pushed: ${IMAGE}" -echo "" -echo "To deploy in Coolify, update the application to use:" -echo " Image: ${IMAGE}" diff --git a/scripts/build-multiarch.sh b/scripts/build-multiarch.sh new file mode 100755 index 0000000..21690bb --- /dev/null +++ b/scripts/build-multiarch.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash +# Build + push multi-arch (linux/amd64 + linux/arm64) claudemesh images. +# +# Usage: +# scripts/build-multiarch.sh [REGISTRY] [TAG] +# +# REGISTRY default: ghcr.io/claudemesh (override for private registry) +# TAG default: $(git rev-parse --short HEAD) +# +# Examples: +# scripts/build-multiarch.sh # → ghcr.io/claudemesh/broker: + web + migrate +# scripts/build-multiarch.sh ghcr.io/myorg latest # → ghcr.io/myorg/broker:latest + web + migrate +# scripts/build-multiarch.sh localhost:5000/claudemesh 0.1.0 # → local registry +# +# Requires: docker buildx with a multi-arch-capable builder. On Docker Desktop +# (Mac/Windows), this is already set up. On Linux CI, run first: +# docker run --privileged --rm tonistiigi/binfmt --install all +# docker buildx create --use --name multiarch +# +# Why multi-arch: Mac dev machines are arm64 (Apple Silicon), VPS is typically +# amd64. Single-arch images force one side into QEMU emulation (2-4x slower, +# noisy warnings, occasional native-binding failures). + +set -euo pipefail + +REGISTRY="${1:-ghcr.io/claudemesh}" +TAG="${2:-$(git rev-parse --short HEAD)}" +GIT_SHA="$(git rev-parse --short HEAD)" + +PLATFORMS="linux/amd64,linux/arm64" + +cd "$(dirname "$0")/.." + +echo "→ Building ${REGISTRY}/{broker,web,migrate}:${TAG} for [${PLATFORMS}]" +echo " GIT_SHA=${GIT_SHA}" +echo "" + +docker buildx build \ + --platform "${PLATFORMS}" \ + --file apps/broker/Dockerfile \ + --build-arg "GIT_SHA=${GIT_SHA}" \ + --tag "${REGISTRY}/broker:${TAG}" \ + --tag "${REGISTRY}/broker:latest" \ + --push \ + . + +docker buildx build \ + --platform "${PLATFORMS}" \ + --file apps/web/Dockerfile \ + --build-arg "NEXT_PUBLIC_URL=${NEXT_PUBLIC_URL:-https://claudemesh.com}" \ + --tag "${REGISTRY}/web:${TAG}" \ + --tag "${REGISTRY}/web:latest" \ + --push \ + . + +docker buildx build \ + --platform "${PLATFORMS}" \ + --file packages/db/Dockerfile \ + --tag "${REGISTRY}/migrate:${TAG}" \ + --tag "${REGISTRY}/migrate:latest" \ + --push \ + . + +echo "" +echo "✓ pushed ${REGISTRY}/{broker,web,migrate}:${TAG} (+ :latest)" +echo " arm64 + amd64 — no QEMU emulation for your adopters"