#!/usr/bin/env bash # Build the static payload, cross-build the Docker image for linux/amd64 # (the typical Portainer host arch), push to the registry. # Usage: scripts/build_and_push.sh [tag] # Default tag = current date + short git sha (if git repo) else 'latest'. # # Env vars: # PLATFORMS - default "linux/amd64". Set to "linux/amd64,linux/arm64" for # multi-arch (registry must support OCI manifest lists; most do). # PY - default ".venv/bin/python" # SKIP_GEN - "1" to skip regeneration of analysis outputs. set -euo pipefail cd "$(dirname "$0")/.." REGISTRY="registry.davidadams.rocks" IMAGE="${REGISTRY}/200feet" PLATFORMS="${PLATFORMS:-linux/amd64}" PY="${PY:-.venv/bin/python}" BUILDER_NAME="200feet-builder" if [[ $# -ge 1 ]]; then TAG="$1" else DATE_TAG="$(date +%Y%m%d-%H%M)" if git rev-parse --short HEAD >/dev/null 2>&1; then SHA="$(git rev-parse --short HEAD)" TAG="${DATE_TAG}-${SHA}" else TAG="${DATE_TAG}" fi fi if [[ "${SKIP_GEN:-0}" != "1" ]]; then echo "==> Regenerating analysis" "$PY" scripts/analyze.py "$PY" scripts/compare_setbacks.py "$PY" scripts/build_web.py fi # Ensure a buildx builder exists with multi-arch / QEMU support. Reuse any # existing docker-container builder rather than always creating ours -- many # M1 setups already have one (e.g. 'multiarch' under Colima). PICKED_BUILDER="" if docker buildx inspect "${BUILDER_NAME}" >/dev/null 2>&1; then PICKED_BUILDER="${BUILDER_NAME}" else # Try first existing docker-container builder, else create ours. while IFS= read -r line; do name=$(awk '{print $1}' <<<"$line" | sed 's/\*$//') driver=$(awk '{print $2}' <<<"$line") if [[ "$driver" == "docker-container" && -n "$name" && "$name" != "NAME/NODE" ]]; then PICKED_BUILDER="$name"; break fi done < <(docker buildx ls 2>/dev/null | tail -n +2) if [[ -z "${PICKED_BUILDER}" ]]; then echo "==> Creating buildx builder '${BUILDER_NAME}'" docker buildx create --name "${BUILDER_NAME}" --driver docker-container >/dev/null docker buildx inspect "${BUILDER_NAME}" --bootstrap >/dev/null PICKED_BUILDER="${BUILDER_NAME}" fi fi docker buildx use "${PICKED_BUILDER}" echo "==> Using buildx builder '${PICKED_BUILDER}'" # Sanity-check the builder actually supports the requested platforms. SUPPORTED=$(docker buildx inspect "${PICKED_BUILDER}" 2>/dev/null | awk -F: '/Platforms/ {print $2}' | tr -d ' ') for plat in $(echo "${PLATFORMS}" | tr ',' ' '); do if ! grep -q "${plat}" <<<"${SUPPORTED}"; then echo "ERROR: builder '${PICKED_BUILDER}' does not support ${plat}." >&2 echo "Supported: ${SUPPORTED}" >&2 exit 1 fi done echo "==> Building & pushing ${IMAGE}:${TAG} for ${PLATFORMS}" docker buildx build \ --builder "${PICKED_BUILDER}" \ --platform "${PLATFORMS}" \ --provenance=false \ --sbom=false \ --tag "${IMAGE}:${TAG}" \ --tag "${IMAGE}:latest" \ --push \ . echo echo "==> Verifying pushed manifest" docker buildx imagetools inspect "${IMAGE}:latest" echo echo "Pushed:" echo " ${IMAGE}:${TAG}" echo " ${IMAGE}:latest" echo "Platforms: ${PLATFORMS}" echo echo "In Portainer: Stacks -> 200feet -> Update -> 'Re-pull image and redeploy'."