#!/usr/bin/env bash # # build_and_push.sh — canonical builder procedure for shorashim images. # # Pin platform to linux/amd64 (Exoscale SKS) so a build on an Apple # Silicon workstation does not silently ship arm64 binaries that the # cluster cannot exec. The Dockerfiles also pin --platform=linux/amd64 # on every FROM line as defense-in-depth; this script is the canonical # build/push path that operators and CI both use. # # Default: linux/amd64 only (cluster-correct, fastest path). # Optional: PLATFORMS=linux/amd64,linux/arm64 ./build_and_push.sh # — multi-arch (slower; preserves local runnability for arm64 devs). # # Prerequisites: # - Docker daemon running # - docker buildx available # - Logged in to exo.container-registry.com (CLI secret from # Harbor → User Profile → CLI Secret) # - Run from the repo root # # What gets pushed (four images): # - vav-pipeline # - shoresh-engine # - talmudic-engine # - korban-processor (azazel_processor is baked into this image) set -euo pipefail REGISTRY="${REGISTRY:-exo.container-registry.com}" PROJECT="${PROJECT:-the-recognition-protocol}" TAG="${TAG:-latest}" PLATFORMS="${PLATFORMS:-linux/amd64}" # Sanity: must be run from repo root (where deploy/ and l1/ live) if [[ ! -d "deploy/docker" || ! -d "l1/torah" ]]; then echo "ERROR: run from the shorashim repo root (where deploy/ and l1/ live)" >&2 exit 1 fi # Sanity: docker buildx if ! docker buildx version >/dev/null 2>&1; then echo "ERROR: docker buildx not available — install Docker Desktop or buildx plugin" >&2 exit 1 fi # Sanity: registry login. We probe with a HEAD against the registry # v2 endpoint; if 401, login is missing. if ! docker info 2>/dev/null | grep -q "$REGISTRY"; then echo "Reminder: run 'docker login $REGISTRY' first (CLI secret from Harbor User Profile)." echo "Continuing — push will fail clearly if not logged in." fi # Create or use the shorashim buildx builder if ! docker buildx inspect shorashim-builder >/dev/null 2>&1; then echo ">> creating buildx builder 'shorashim-builder'" docker buildx create --name shorashim-builder --use else docker buildx use shorashim-builder fi docker buildx inspect --bootstrap >/dev/null # Source dir → image name → Dockerfile mapping. # korban_processor's Dockerfile also COPYs azazel_processor (see # Dockerfile.korban_processor — AZAZEL CO-RESIDENT section). build_one() { local component="$1" local image="$2" local dockerfile="deploy/docker/Dockerfile.${component}" if [[ ! -f "$dockerfile" ]]; then echo "ERROR: $dockerfile not found" >&2 return 1 fi echo "" echo "================================================================" echo ">> building ${image}:${TAG} for ${PLATFORMS}" echo " dockerfile: ${dockerfile}" echo "================================================================" docker buildx build \ --platform "$PLATFORMS" \ --file "$dockerfile" \ --tag "${REGISTRY}/${PROJECT}/${image}:${TAG}" \ --push \ . } build_one vav_pipeline vav-pipeline build_one shoresh_engine shoresh-engine build_one talmudic_engine talmudic-engine build_one korban_processor korban-processor echo "" echo "================================================================" echo ">> all four images built and pushed for ${PLATFORMS}" echo "================================================================" echo "" echo "Verify from the cluster (after kohen has kubeconfig loaded):" echo " kubectl get nodes -o jsonpath='{.items[0].status.nodeInfo.architecture}'" echo " # expected: amd64" echo "" echo "Verify image manifests:" echo " for img in vav-pipeline shoresh-engine talmudic-engine korban-processor; do" echo " docker manifest inspect \"${REGISTRY}/${PROJECT}/\$img:${TAG}\" \\" echo " | jq -r '.architecture // .manifests[].platform.architecture' \\" echo " | sort -u" echo " done" echo "" echo "Then re-run kohen gate 0i in KOHEN_PROMPT.md."