Assist_Design/scripts/plesk/build-images.sh

161 lines
5.7 KiB
Bash
Raw Normal View History

#!/usr/bin/env bash
# 🐳 Build production images for Plesk and save as .tar
# - Builds apps/portal (frontend) and apps/bff (backend)
# - Tags both with :latest and optional version/sha tag
# - Saves tarballs in project root for easy Plesk upload
set -Eeuo pipefail
IFS=$'\n\t'
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
IMAGE_FRONTEND_NAME="${IMAGE_FRONTEND_NAME:-portal-frontend}"
IMAGE_BACKEND_NAME="${IMAGE_BACKEND_NAME:-portal-backend}"
# Optional explicit tag via env or flag; defaults to git short sha + date
IMAGE_TAG="${IMAGE_TAG:-}"
OUTPUT_DIR="${OUTPUT_DIR:-$PROJECT_ROOT}"
PUSH_REMOTE="${PUSH_REMOTE:-}" # e.g. ghcr.io/<org>
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'
log() { echo -e "${GREEN}[PLESK-BUILD] $*${NC}"; }
warn() { echo -e "${YELLOW}[PLESK-BUILD] $*${NC}"; }
fail() { echo -e "${RED}[PLESK-BUILD] ERROR: $*${NC}"; exit 1; }
usage() {
cat <<EOF
Build production Docker images and save tarballs for Plesk.
Usage: $0 [--tag <tag>] [--output <dir>] [--push <registry>] [--no-save]
Options:
--tag <tag> Tag to add in addition to 'latest' (e.g. v1.2.3 or abc123)
--output <dir> Directory to write tar files (default: project root)
--push <registry> Also tag and push to registry (e.g. ghcr.io/org or docker.io/user)
--no-save Build and tag images but do not write tar files
Env vars:
IMAGE_FRONTEND_NAME, IMAGE_BACKEND_NAME, IMAGE_TAG, OUTPUT_DIR, PUSH_REMOTE
Examples:
$0 --tag $(date +%Y%m%d)-$(git -C "$PROJECT_ROOT" rev-parse --short HEAD)
PUSH_REMOTE=ghcr.io/acme $0 --tag v1.0.0
EOF
}
SAVE_TARS=1
while [[ $# -gt 0 ]]; do
case "$1" in
--tag)
IMAGE_TAG="${2:-}"; shift 2 ;;
--output)
OUTPUT_DIR="${2:-}"; shift 2 ;;
--push)
PUSH_REMOTE="${2:-}"; shift 2 ;;
--no-save)
SAVE_TARS=0; shift ;;
-h|--help)
usage; exit 0 ;;
*)
warn "Unknown option: $1"; usage; exit 1 ;;
esac
done
command -v docker >/dev/null 2>&1 || fail "Docker is required."
cd "$PROJECT_ROOT"
[[ -f apps/portal/Dockerfile ]] || fail "Missing apps/portal/Dockerfile"
[[ -f apps/bff/Dockerfile ]] || fail "Missing apps/bff/Dockerfile"
if [[ -z "${IMAGE_TAG}" ]]; then
if git -C "$PROJECT_ROOT" rev-parse --short HEAD >/dev/null 2>&1; then
GIT_SHA="$(git -C "$PROJECT_ROOT" rev-parse --short HEAD)"
IMAGE_TAG="$(date +%Y%m%d)-$GIT_SHA"
else
IMAGE_TAG="$(date +%Y%m%d)"
fi
fi
log "🔨 Building frontend image (${IMAGE_FRONTEND_NAME}:latest, ${IMAGE_FRONTEND_NAME}:${IMAGE_TAG})"
docker build \
--file apps/portal/Dockerfile \
--tag "${IMAGE_FRONTEND_NAME}:latest" \
--tag "${IMAGE_FRONTEND_NAME}:${IMAGE_TAG}" \
--label "org.opencontainers.image.title=Customer Portal Frontend" \
--label "org.opencontainers.image.version=${IMAGE_TAG}" \
--label "org.opencontainers.image.source=$(git -C "$PROJECT_ROOT" config --get remote.origin.url 2>/dev/null || echo unknown)" \
.
log "🔨 Building backend image (${IMAGE_BACKEND_NAME}:latest, ${IMAGE_BACKEND_NAME}:${IMAGE_TAG})"
docker build \
--file apps/bff/Dockerfile \
--tag "${IMAGE_BACKEND_NAME}:latest" \
--tag "${IMAGE_BACKEND_NAME}:${IMAGE_TAG}" \
--label "org.opencontainers.image.title=Customer Portal Backend" \
--label "org.opencontainers.image.version=${IMAGE_TAG}" \
--label "org.opencontainers.image.source=$(git -C "$PROJECT_ROOT" config --get remote.origin.url 2>/dev/null || echo unknown)" \
.
if [[ "${SAVE_TARS}" -eq 1 ]]; then
mkdir -p "$OUTPUT_DIR"
FRONT_TAR_LATEST="$OUTPUT_DIR/${IMAGE_FRONTEND_NAME}.latest.tar"
BACK_TAR_LATEST="$OUTPUT_DIR/${IMAGE_BACKEND_NAME}.latest.tar"
FRONT_TAR_TAGGED="$OUTPUT_DIR/${IMAGE_FRONTEND_NAME}.${IMAGE_TAG}.tar"
BACK_TAR_TAGGED="$OUTPUT_DIR/${IMAGE_BACKEND_NAME}.${IMAGE_TAG}.tar"
log "💾 Saving tarballs to $OUTPUT_DIR ..."
docker save -o "$FRONT_TAR_LATEST" "${IMAGE_FRONTEND_NAME}:latest"
docker save -o "$BACK_TAR_LATEST" "${IMAGE_BACKEND_NAME}:latest"
docker save -o "$FRONT_TAR_TAGGED" "${IMAGE_FRONTEND_NAME}:${IMAGE_TAG}"
docker save -o "$BACK_TAR_TAGGED" "${IMAGE_BACKEND_NAME}:${IMAGE_TAG}"
log "🔐 Generating checksums for integrity verification..."
sha256sum "$FRONT_TAR_TAGGED" > "${FRONT_TAR_TAGGED}.sha256"
sha256sum "$BACK_TAR_TAGGED" > "${BACK_TAR_TAGGED}.sha256"
log "✅ Wrote:"
echo " - $FRONT_TAR_LATEST"
echo " - $BACK_TAR_LATEST"
echo " - $FRONT_TAR_TAGGED"
echo " - $BACK_TAR_TAGGED"
echo " - ${FRONT_TAR_TAGGED}.sha256"
echo " - ${BACK_TAR_TAGGED}.sha256"
fi
if [[ -n "${PUSH_REMOTE}" ]]; then
FE_REMOTE_LATEST="${PUSH_REMOTE%/}/${IMAGE_FRONTEND_NAME}:latest"
FE_REMOTE_TAGGED="${PUSH_REMOTE%/}/${IMAGE_FRONTEND_NAME}:${IMAGE_TAG}"
BE_REMOTE_LATEST="${PUSH_REMOTE%/}/${IMAGE_BACKEND_NAME}:latest"
BE_REMOTE_TAGGED="${PUSH_REMOTE%/}/${IMAGE_BACKEND_NAME}:${IMAGE_TAG}"
log "📤 Tagging for remote: ${PUSH_REMOTE}"
docker tag "${IMAGE_FRONTEND_NAME}:latest" "$FE_REMOTE_LATEST"
docker tag "${IMAGE_FRONTEND_NAME}:${IMAGE_TAG}" "$FE_REMOTE_TAGGED"
docker tag "${IMAGE_BACKEND_NAME}:latest" "$BE_REMOTE_LATEST"
docker tag "${IMAGE_BACKEND_NAME}:${IMAGE_TAG}" "$BE_REMOTE_TAGGED"
log "🚀 Pushing to remote registry (ensure you are logged in)"
docker push "$FE_REMOTE_LATEST"
docker push "$FE_REMOTE_TAGGED"
docker push "$BE_REMOTE_LATEST"
docker push "$BE_REMOTE_TAGGED"
fi
log "🎉 Done!"
log ""
log "Next steps:"
log " 1. Upload .tar files to your Plesk server"
log " 2. Load images: docker load -i portal-frontend.${IMAGE_TAG}.tar"
log " 3. Verify checksums: sha256sum -c portal-frontend.${IMAGE_TAG}.tar.sha256"
log " 4. Update Portainer stack with new image tag: ${IMAGE_TAG}"
log ""
log "See docker/portainer/PORTAINER-GUIDE.md for detailed instructions."