#!/bin/bash set -euo pipefail if [ "$#" -ne 1 ]; then echo "Usage: $0 " exit 1 fi TARGET_DIR="$1" TARGET_ABS="$(cd "$TARGET_DIR" && pwd)" COMMON_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" BASENAME="$(basename "$TARGET_ABS")" BUILD_DIR="$TARGET_ABS/build" DOCKERFILE="$TARGET_ABS/Dockerfile.alpine-musl" if [ ! -f "$DOCKERFILE" ]; then echo "ERROR: Missing Dockerfile: $DOCKERFILE" exit 1 fi if ! command -v docker >/dev/null 2>&1; then echo "ERROR: docker is not installed or not in PATH" exit 1 fi if ! docker info >/dev/null 2>&1; then echo "ERROR: docker daemon is not reachable" exit 1 fi HOST_ARCH="$(uname -m)" REQUESTED_ARCH="${ARCH:-}" if [ -n "$REQUESTED_ARCH" ]; then case "$REQUESTED_ARCH" in arm64|aarch64) PLATFORM="linux/arm64" OUTPUT_ARCH="arm64" ;; amd64|x86_64) PLATFORM="linux/amd64" OUTPUT_ARCH="x86_64" ;; *) echo "ERROR: Unsupported ARCH='$REQUESTED_ARCH' (supported: arm64, amd64)" exit 1 ;; esac else case "$HOST_ARCH" in x86_64) PLATFORM="linux/amd64" OUTPUT_ARCH="x86_64" ;; aarch64|arm64) PLATFORM="linux/arm64" OUTPUT_ARCH="arm64" ;; *) echo "WARNING: Unknown host architecture '$HOST_ARCH', defaulting to linux/amd64" PLATFORM="linux/amd64" OUTPUT_ARCH="$HOST_ARCH" ;; esac fi OUTPUT_NAME="${BASENAME}_static_${OUTPUT_ARCH}" BASE_IMAGE_TAG="n-os-tr/alpine-musl-base:3.19" APP_IMAGE_TAG="n-os-tr/${BASENAME}-musl-builder:latest" mkdir -p "$BUILD_DIR" echo "==========================================" echo "n-OS-tr Alpine/musl static build" echo "==========================================" echo "Target: $TARGET_ABS" echo "Platform: $PLATFORM" echo "Output: $BUILD_DIR/$OUTPUT_NAME" echo "" echo "[1/3] Building shared base image ($BASE_IMAGE_TAG)" docker build \ --platform "$PLATFORM" \ -f "$COMMON_DIR/Dockerfile.alpine-musl" \ -t "$BASE_IMAGE_TAG" \ "$COMMON_DIR" echo "[2/3] Building application image ($APP_IMAGE_TAG)" docker build \ --platform "$PLATFORM" \ -f "$DOCKERFILE" \ -t "$APP_IMAGE_TAG" \ "$TARGET_ABS" echo "[3/3] Extracting binary" CONTAINER_ID="$(docker create "$APP_IMAGE_TAG" "/$BASENAME")" trap 'docker rm -f "$CONTAINER_ID" >/dev/null 2>&1 || true' EXIT docker cp "$CONTAINER_ID:/$BASENAME" "$BUILD_DIR/$OUTPUT_NAME" chmod +x "$BUILD_DIR/$OUTPUT_NAME" FILE_INFO="$(file "$BUILD_DIR/$OUTPUT_NAME")" echo "$FILE_INFO" if LDD_OUT="$(ldd "$BUILD_DIR/$OUTPUT_NAME" 2>&1 || true)"; then echo "$LDD_OUT" fi echo "Built: $BUILD_DIR/$OUTPUT_NAME" echo "Size: $(stat -c '%s bytes' "$BUILD_DIR/$OUTPUT_NAME")"