diff --git a/ops/build-image.sh b/ops/build-image.sh index b1342c3..4fff106 100755 --- a/ops/build-image.sh +++ b/ops/build-image.sh @@ -1,28 +1,35 @@ #!/bin/sh -# Build a Docker image locally. +# Build a Docker image. If an image name is provided, builds multi-arch and pushes to registry. +# Otherwise builds locally for the current platform only. # -# Usage (interactive — prompts for missing values): +# Usage (interactive): # ./ops/build-image.sh # -# Usage (non-interactive — all values as positional args): -# ./ops/build-image.sh +# Usage (non-interactive): +# ./ops/build-image.sh [image] # -# Example: -# ./ops/build-image.sh v1.0 registry.example.com/myorg/myapp +# Examples: +# ./ops/build-image.sh # prompts for tag and image +# ./ops/build-image.sh v1.0 # prompts for image +# ./ops/build-image.sh v1.0 registry.example.com/org/myapp # local only (no push) +# ./ops/build-image.sh v1.0 "" # local build, no push set -eu ROOT_DIR=$(CDPATH= cd -- "$(dirname "$0")/.." && pwd) -command -v docker >/dev/null 2>&1 || { echo "error: docker not found in PATH" >&2; exit 1; } +die() { echo "error: $*" >&2; exit 1; } + +command -v docker >/dev/null 2>&1 || die "docker not found in PATH" DEFAULT_TAG=$(git -C "${ROOT_DIR}" rev-parse --short HEAD 2>/dev/null || echo dev) ask() { + # $1=varname $2=prompt $3=default if [ -n "$3" ]; then printf "%s [%s]: " "$2" "$3" >&2 else - printf "%s: " "$2" >&2 + printf "%s (leave empty to build locally only): " "$2" >&2 fi read -r _val eval "$1=\"\${_val:-$3}\"" @@ -39,9 +46,46 @@ else ask IMAGE "Image" "" fi -echo "building ${IMAGE}:${IMAGE_TAG}" -docker build \ - -f "${ROOT_DIR}/Dockerfile" \ - -t "${IMAGE}:${IMAGE_TAG}" \ - -t "${IMAGE}:latest" \ - "${ROOT_DIR}" +if [ -n "${IMAGE}" ]; then + # multi-arch build + push + docker buildx version >/dev/null 2>&1 || die "docker buildx not available" + + PLATFORMS="${PLATFORMS:-linux/amd64,linux/arm64}" + BUILDER_NAME="jukebox-multiarch" + + if ! docker buildx inspect "${BUILDER_NAME}" >/dev/null 2>&1; then + echo "creating buildx builder: ${BUILDER_NAME}" + docker buildx create \ + --name "${BUILDER_NAME}" \ + --driver docker-container \ + --bootstrap + fi + docker buildx use "${BUILDER_NAME}" + + echo "building and pushing ${IMAGE}:${IMAGE_TAG} (${PLATFORMS})" + docker buildx build \ + --platform "${PLATFORMS}" \ + --file "${ROOT_DIR}/Dockerfile" \ + -t "${IMAGE}:${IMAGE_TAG}" \ + -t "${IMAGE}:latest" \ + --push \ + "${ROOT_DIR}" + + echo "" + echo "pushed:" + echo " ${IMAGE}:${IMAGE_TAG}" + echo " ${IMAGE}:latest" +else + # local build only + echo "building locally (no push)" + docker build \ + --file "${ROOT_DIR}/Dockerfile" \ + -t "jukebox-maker:${IMAGE_TAG}" \ + -t "jukebox-maker:latest" \ + "${ROOT_DIR}" + + echo "" + echo "built:" + echo " jukebox-maker:${IMAGE_TAG}" + echo " jukebox-maker:latest" +fi diff --git a/ops/push-image.sh b/ops/push-image.sh deleted file mode 100755 index 3b16483..0000000 --- a/ops/push-image.sh +++ /dev/null @@ -1,76 +0,0 @@ -#!/bin/sh -# Build a multi-arch Docker image and push it to a container registry. -# -# Usage (interactive — prompts for missing values): -# ./ops/push-image.sh -# -# Usage (non-interactive — all values as positional args): -# ./ops/push-image.sh -# -# Example: -# ./ops/push-image.sh v1.0 registry.example.com/myorg/myapp -# -# Assumes docker is already logged in to the target registry. - -set -eu - -ROOT_DIR=$(CDPATH= cd -- "$(dirname "$0")/.." && pwd) - -die() { echo "error: $*" >&2; exit 1; } - -command -v docker >/dev/null 2>&1 || die "docker not found in PATH" -command -v git >/dev/null 2>&1 || die "git not found in PATH" -docker buildx version >/dev/null 2>&1 || die "docker buildx not available" - -DEFAULT_TAG=$(git -C "${ROOT_DIR}" rev-parse --short HEAD 2>/dev/null || echo dev) -PLATFORMS="${PLATFORMS:-linux/amd64,linux/arm64}" - -ask() { - if [ -n "$3" ]; then - printf "%s [%s]: " "$2" "$3" >&2 - else - printf "%s: " "$2" >&2 - fi - read -r _val - eval "$1=\"\${_val:-$3}\"" -} - -if [ $# -ge 2 ]; then - IMAGE_TAG="$1" - IMAGE="$2" -elif [ $# -ge 1 ]; then - IMAGE_TAG="$1" - ask IMAGE "Image" "" -else - ask IMAGE_TAG "Tag" "${DEFAULT_TAG}" - ask IMAGE "Image" "" -fi - -echo "" -echo "image : ${IMAGE}" -echo "tag : ${IMAGE_TAG}" -echo "platforms: ${PLATFORMS}" -echo "" - -BUILDER_NAME="jukebox-multiarch" -if ! docker buildx inspect "${BUILDER_NAME}" >/dev/null 2>&1; then - echo "creating buildx builder: ${BUILDER_NAME}" - docker buildx create \ - --name "${BUILDER_NAME}" \ - --driver docker-container \ - --bootstrap -fi -docker buildx use "${BUILDER_NAME}" - -docker buildx build \ - --platform "${PLATFORMS}" \ - --file "${ROOT_DIR}/Dockerfile" \ - -t "${IMAGE}:${IMAGE_TAG}" \ - -t "${IMAGE}:latest" \ - --push \ - "${ROOT_DIR}" - -echo "" -echo "pushed:" -echo " ${IMAGE}:${IMAGE_TAG}" -echo " ${IMAGE}:latest"