#!/usr/bin/env bash # ============================================================================= # recipe-importer — Docker image build script # ============================================================================= # Location: /home/kisfenyo/build/recipe-importer/build.sh # # Copies source from the git repo and builds the Docker image. # Build artifacts stay here — the git repo stays clean. # # Usage: # ./build.sh # Build for current platform, tag as :dev # ./build.sh 0.1.0 # Build with version tag # ./build.sh 0.1.0 --push # Build + push to Gitea registry # ./build.sh 0.1.0 --multiarch # Build amd64+arm64 + push # ============================================================================= set -euo pipefail # --- Configuration --- REPO_DIR="/home/kisfenyo/git/recipe-importer" REGISTRY="gitea.dooplex.hu/admin" IMAGE="${REGISTRY}/recipe-importer" SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" BUILD_DIR="${SCRIPT_DIR}/workspace" # --- Parse arguments --- VERSION="${1:-dev}" ACTION="${2:-}" # --- Colors --- RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; NC='\033[0m' info() { echo -e "${GREEN}[INFO]${NC} $*"; } warn() { echo -e "${YELLOW}[WARN]${NC} $*"; } error() { echo -e "${RED}[ERROR]${NC} $*"; } step() { echo -e "${CYAN}[STEP]${NC} $*"; } # --- Pre-flight checks --- if [[ ! -d "${REPO_DIR}" ]]; then error "Source not found: ${REPO_DIR}" error "Clone the repo first: git clone https://gitea.dooplex.hu/admin/recipe-importer.git ${REPO_DIR}" exit 1 fi if ! command -v docker &>/dev/null; then error "Docker not found." exit 1 fi GIT_COMMIT="unknown" if [[ -d "${REPO_DIR}/.git" ]]; then GIT_COMMIT=$(cd "${REPO_DIR}" && git rev-parse --short HEAD 2>/dev/null || echo "unknown") fi echo "" info "╔══════════════════════════════════════╗" info "║ recipe-importer image builder ║" info "╚══════════════════════════════════════╝" info "Version: ${VERSION}" info "Commit: ${GIT_COMMIT}" info "Source: ${REPO_DIR}" info "Build dir: ${BUILD_DIR}" info "Image: ${IMAGE}:${VERSION}" echo "" # ========================================================================= # Step 1: Pull latest & sync source # ========================================================================= step "1/2 — Syncing source to workspace..." cd "${REPO_DIR}" git pull --ff-only 2>/dev/null || warn "git pull failed (offline or dirty tree?)" rm -rf "${BUILD_DIR}" mkdir -p "${BUILD_DIR}" rsync -a --delete \ --exclude '.git' \ --exclude 'mindmegette-examples' \ --exclude '__pycache__' \ --exclude '*.pyc' \ "${REPO_DIR}/" "${BUILD_DIR}/" # Verify structure for required in Dockerfile requirements.txt app/main.py app/scraper.py app/mealie.py; do if [[ ! -f "${BUILD_DIR}/${required}" ]]; then error "Missing: ${required}" exit 1 fi done info "Source synced ✓" # ========================================================================= # Step 2: Docker build # ========================================================================= step "2/2 — Building Docker image..." cd "${BUILD_DIR}" BUILD_ARGS=( --build-arg "VERSION=${VERSION}" ) case "${ACTION}" in --push) info "Building for current platform + pushing..." docker build "${BUILD_ARGS[@]}" \ -t "${IMAGE}:${VERSION}" \ -t "${IMAGE}:latest" \ . info "Pushing..." docker push "${IMAGE}:${VERSION}" docker push "${IMAGE}:latest" ;; --multiarch) info "Building multi-arch (amd64 + arm64) + pushing..." if ! docker buildx inspect felhom-builder &>/dev/null; then info "Creating buildx builder (one-time setup)..." docker buildx create --name felhom-builder --use --bootstrap else docker buildx use felhom-builder fi docker buildx build "${BUILD_ARGS[@]}" \ --platform linux/amd64,linux/arm64 \ -t "${IMAGE}:${VERSION}" \ -t "${IMAGE}:latest" \ --push \ . ;; *) info "Building for current platform (local only)..." docker build "${BUILD_ARGS[@]}" \ -t "${IMAGE}:${VERSION}" \ -t "${IMAGE}:latest" \ . ;; esac # ========================================================================= # Summary # ========================================================================= echo "" info "╔══════════════════════════════════════╗" info "║ Build complete ✓ ║" info "╚══════════════════════════════════════╝" info "Image: ${IMAGE}:${VERSION}" SIZE=$(docker image inspect "${IMAGE}:${VERSION}" --format='{{.Size}}' 2>/dev/null || echo "") if [[ -n "${SIZE}" ]]; then SIZE_HUMAN=$(numfmt --to=iec "${SIZE}" 2>/dev/null || echo "${SIZE} bytes") info "Size: ${SIZE_HUMAN}" fi echo "" if [[ "${ACTION}" == "" ]]; then info "Image is local only. To push:" info " ./build.sh ${VERSION} --push # current arch" info " ./build.sh ${VERSION} --multiarch # amd64 + arm64" fi