towerops/k8s/base-image/build.sh
Graham McIntire d92443d91b
feat: add podman support and Docker Hub push to base image builder
Enhanced base image build system with:

Container Engine Support:
- Auto-detect podman or docker (prefers podman if both installed)
- All scripts work with either engine seamlessly
- No configuration needed

Docker Hub Integration:
- Push to both GitLab and Docker Hub registries
- GitLab: registry.gitlab.com/towerops/towerops/elixir-runtime
- Docker Hub: docker.io/gmcintire/elixir-runtime
- Both versioned and :latest tags pushed to each

Build Script:
- Detect and use $CONTAINER_CMD for all operations
- Show which container engine is being used in output
- Tag and push to both registries automatically

Makefile:
- Add CONTAINER_CMD variable with auto-detection
- Add DOCKERHUB_REGISTRY configuration
- Update all targets to use detected container engine
- Add login-dockerhub target for Docker Hub authentication
- Update push target to push to both registries

Documentation:
- Document podman/docker auto-detection
- Update login instructions for both registries
- Update troubleshooting with examples for both engines

This makes the build system more flexible and accessible to users
who prefer podman over docker, while also publishing to the public
Docker Hub registry for easier access.
2026-01-25 09:18:03 -06:00

125 lines
5.6 KiB
Bash
Executable file

#!/usr/bin/env bash
set -euo pipefail
# Build script for minimal Debian base image with Erlang/OTP and Elixir
# This script can be re-run to rebuild with latest packages
# Detect container engine (podman or docker)
if command -v podman &> /dev/null; then
CONTAINER_CMD="podman"
elif command -v docker &> /dev/null; then
CONTAINER_CMD="docker"
else
echo "Error: Neither podman nor docker found. Please install one of them."
exit 1
fi
# Configuration
REGISTRY="${REGISTRY:-registry.gitlab.com/towerops/towerops}"
IMAGE_NAME="${IMAGE_NAME:-elixir-runtime}"
ERLANG_VERSION="${ERLANG_VERSION:-28.3}"
ELIXIR_VERSION="${ELIXIR_VERSION:-1.19.5}"
DEBIAN_VERSION="${DEBIAN_VERSION:-trixie-20251229-slim}"
# Build timestamp for tracking
BUILD_DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
GIT_SHA=$(git rev-parse --short HEAD 2>/dev/null || echo "unknown")
# Image tags
TAG_FULL="${ERLANG_VERSION}-elixir-${ELIXIR_VERSION}-debian-trixie"
TAG_LATEST="latest"
TAG_DATED="${TAG_FULL}-${BUILD_DATE//[:-]*/}" # YYYY-MM-DD format
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "Building Minimal Debian Base Image"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "Container: ${CONTAINER_CMD}"
echo "Registry: ${REGISTRY}"
echo "Image: ${IMAGE_NAME}"
echo "Erlang: ${ERLANG_VERSION}"
echo "Elixir: ${ELIXIR_VERSION}"
echo "Debian: ${DEBIAN_VERSION}"
echo "Build Date: ${BUILD_DATE}"
echo "Git SHA: ${GIT_SHA}"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
# Build the image with no cache to ensure latest packages
echo ""
echo "🔨 Building image (no cache, pulling latest packages)..."
$CONTAINER_CMD build \
--no-cache \
--pull \
--build-arg DEBIAN_VERSION="${DEBIAN_VERSION}" \
--build-arg ERLANG_VERSION="${ERLANG_VERSION}" \
--build-arg ELIXIR_VERSION="${ELIXIR_VERSION}" \
--label "build.date=${BUILD_DATE}" \
--label "build.git-sha=${GIT_SHA}" \
--label "erlang.version=${ERLANG_VERSION}" \
--label "elixir.version=${ELIXIR_VERSION}" \
-t "${REGISTRY}/${IMAGE_NAME}:${TAG_FULL}" \
-t "${REGISTRY}/${IMAGE_NAME}:${TAG_LATEST}" \
-t "${REGISTRY}/${IMAGE_NAME}:${TAG_DATED}" \
-f Dockerfile \
.
echo ""
echo "✅ Build complete!"
echo ""
echo "Image tags created:"
echo " - ${REGISTRY}/${IMAGE_NAME}:${TAG_FULL}"
echo " - ${REGISTRY}/${IMAGE_NAME}:${TAG_LATEST}"
echo " - ${REGISTRY}/${IMAGE_NAME}:${TAG_DATED}"
echo ""
# Show image size
echo "📦 Image size:"
$CONTAINER_CMD images "${REGISTRY}/${IMAGE_NAME}:${TAG_LATEST}" --format "table {{.Repository}}:{{.Tag}}\t{{.Size}}"
echo ""
# Verify image works
echo "🔍 Verifying image..."
$CONTAINER_CMD run --rm "${REGISTRY}/${IMAGE_NAME}:${TAG_LATEST}" erl -eval 'io:format("Erlang/OTP: ~s~n", [erlang:system_info(otp_release)]), halt().' -noshell
$CONTAINER_CMD run --rm "${REGISTRY}/${IMAGE_NAME}:${TAG_LATEST}" elixir --version
echo ""
# Ask if user wants to push
read -p "Push to registries? (y/N) " -n 1 -r
echo ""
if [[ $REPLY =~ ^[Yy]$ ]]; then
echo "🚀 Pushing to GitLab registry..."
$CONTAINER_CMD push "${REGISTRY}/${IMAGE_NAME}:${TAG_FULL}"
$CONTAINER_CMD push "${REGISTRY}/${IMAGE_NAME}:${TAG_LATEST}"
$CONTAINER_CMD push "${REGISTRY}/${IMAGE_NAME}:${TAG_DATED}"
echo ""
echo "🚀 Tagging for Docker Hub..."
DOCKERHUB_REGISTRY="docker.io/gmcintire"
$CONTAINER_CMD tag "${REGISTRY}/${IMAGE_NAME}:${TAG_FULL}" "${DOCKERHUB_REGISTRY}/${IMAGE_NAME}:${TAG_FULL}"
$CONTAINER_CMD tag "${REGISTRY}/${IMAGE_NAME}:${TAG_LATEST}" "${DOCKERHUB_REGISTRY}/${IMAGE_NAME}:${TAG_LATEST}"
$CONTAINER_CMD tag "${REGISTRY}/${IMAGE_NAME}:${TAG_DATED}" "${DOCKERHUB_REGISTRY}/${IMAGE_NAME}:${TAG_DATED}"
echo "🚀 Pushing to Docker Hub..."
$CONTAINER_CMD push "${DOCKERHUB_REGISTRY}/${IMAGE_NAME}:${TAG_FULL}"
$CONTAINER_CMD push "${DOCKERHUB_REGISTRY}/${IMAGE_NAME}:${TAG_LATEST}"
$CONTAINER_CMD push "${DOCKERHUB_REGISTRY}/${IMAGE_NAME}:${TAG_DATED}"
echo ""
echo "✅ Pushed successfully to both registries!"
echo ""
echo "Update your main Dockerfile to use:"
echo " GitLab: ARG RUNNER_IMAGE=\"${REGISTRY}/${IMAGE_NAME}:${TAG_FULL}\""
echo " Docker Hub: ARG RUNNER_IMAGE=\"${DOCKERHUB_REGISTRY}/${IMAGE_NAME}:${TAG_FULL}\""
else
echo "⏭️ Skipping push. To push later, run:"
echo " $CONTAINER_CMD push ${REGISTRY}/${IMAGE_NAME}:${TAG_FULL}"
echo " $CONTAINER_CMD push ${REGISTRY}/${IMAGE_NAME}:${TAG_LATEST}"
echo " $CONTAINER_CMD push ${REGISTRY}/${IMAGE_NAME}:${TAG_DATED}"
echo " $CONTAINER_CMD push docker.io/gmcintire/${IMAGE_NAME}:${TAG_FULL}"
echo " $CONTAINER_CMD push docker.io/gmcintire/${IMAGE_NAME}:${TAG_LATEST}"
echo " $CONTAINER_CMD push docker.io/gmcintire/${IMAGE_NAME}:${TAG_DATED}"
fi
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "Done!"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"