#!/bin/bash # build.sh - Service Image 빌드 스크립트 (Base Image 활용) set -e # 변수 설정 IMAGE_NAME="restaurant-api" IMAGE_TAG="${1:-latest}" ACR_NAME="${2:-acrdigitalgarage03}" RESOURCE_GROUP="${3:-rg-digitalgarage-03}" BASE_IMAGE_TAG="${4:-latest}" # ACR URL 자동 구성 if [ -n "${ACR_NAME}" ]; then REGISTRY="${ACR_NAME}.azurecr.io" FULL_IMAGE_NAME="${REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}" BASE_IMAGE="${REGISTRY}/restaurant-api-base:${BASE_IMAGE_TAG}" else FULL_IMAGE_NAME="${IMAGE_NAME}:${IMAGE_TAG}" BASE_IMAGE="restaurant-api-base:${BASE_IMAGE_TAG}" fi # 고정된 Dockerfile 경로 DOCKERFILE_PATH="deployment/container/Dockerfile" BUILD_CONTEXT="." echo "=====================================================" echo " 카카오 API 음식점 수집 서비스 Service Image 빌드" echo "=====================================================" echo "Service 이미지명: ${FULL_IMAGE_NAME}" echo "Base 이미지: ${BASE_IMAGE}" if [ -n "${ACR_NAME}" ]; then echo "ACR 이름: ${ACR_NAME}" echo "리소스 그룹: ${RESOURCE_GROUP}" fi echo "빌드 시작: $(date)" echo "" # 사용법 표시 함수 show_usage() { echo "사용법:" echo " $0 [IMAGE_TAG] [ACR_NAME] [RESOURCE_GROUP] [BASE_IMAGE_TAG]" echo "" echo "파라미터:" echo " IMAGE_TAG : Service 이미지 태그 (기본값: latest)" echo " ACR_NAME : Azure Container Registry 이름" echo " RESOURCE_GROUP: Azure 리소스 그룹" echo " BASE_IMAGE_TAG: Base 이미지 태그 (기본값: latest)" echo "" echo "예시:" echo " $0 v1.0.0 # 로컬 빌드만" echo " $0 v1.0.0 acrdigitalgarage01 rg-digitalgarage-03 # ACR 빌드 + 푸시" echo " $0 v1.0.0 acrdigitalgarage01 rg-digitalgarage-03 v2.0.0 # 특정 Base Image 사용" echo "" echo "전제조건:" echo " Base Image가 먼저 빌드되어 있어야 합니다:" echo " ./build-base.sh ${BASE_IMAGE_TAG} [ACR_NAME] [RESOURCE_GROUP]" } # ACR 로그인 함수 acr_login() { local acr_name="$1" local resource_group="$2" echo "🔐 Azure Container Registry 로그인 중..." if ! command -v az &> /dev/null; then echo "❌ Azure CLI (az)가 설치되지 않았습니다." exit 1 fi if ! command -v jq &> /dev/null; then echo "❌ jq가 설치되지 않았습니다." exit 1 fi if ! az account show &> /dev/null; then echo "❌ Azure에 로그인되지 않았습니다." echo "로그인 명령: az login" exit 1 fi local credential_json credential_json=$(az acr credential show --name "${acr_name}" --resource-group "${resource_group}" 2>/dev/null) if [ $? -ne 0 ]; then echo "❌ ACR credential 조회 실패" exit 1 fi local username local password username=$(echo "${credential_json}" | jq -r '.username') password=$(echo "${credential_json}" | jq -r '.passwords[0].value') if [ -z "${username}" ] || [ -z "${password}" ] || [ "${username}" == "null" ] || [ "${password}" == "null" ]; then echo "❌ ACR credential 파싱 실패" exit 1 fi echo "🔐 Docker 로그인 실행 중..." echo "${password}" | docker login "${REGISTRY}" -u "${username}" --password-stdin if [ $? -eq 0 ]; then echo "✅ ACR 로그인 성공!" return 0 else echo "❌ ACR 로그인 실패" exit 1 fi } # 파라미터 검증 if [ "$1" == "--help" ] || [ "$1" == "-h" ]; then show_usage exit 0 fi if [ -n "${ACR_NAME}" ] && [ -z "${RESOURCE_GROUP}" ]; then echo "❌ ACR_NAME이 제공된 경우 RESOURCE_GROUP도 필요합니다." echo "" show_usage exit 1 fi # 필수 파일 확인 echo "📁 필수 파일 확인 중..." if [ ! -f "app/main.py" ]; then echo "❌ app/main.py 파일을 찾을 수 없습니다." exit 1 fi if [ ! -f "app/requirements.txt" ]; then echo "❌ app/requirements.txt 파일을 찾을 수 없습니다." exit 1 fi if [ ! -f "${DOCKERFILE_PATH}" ]; then echo "❌ ${DOCKERFILE_PATH} 파일을 찾을 수 없습니다." exit 1 fi echo "✅ 모든 필수 파일이 확인되었습니다." echo "📄 Dockerfile: ${DOCKERFILE_PATH}" echo "🏗️ 빌드 컨텍스트: ${BUILD_CONTEXT}" # Base Image 존재 확인 echo "" echo "🔍 Base Image 확인 중..." if docker image inspect "${BASE_IMAGE}" >/dev/null 2>&1; then echo "✅ Base Image 확인됨: ${BASE_IMAGE}" else echo "❌ Base Image를 찾을 수 없습니다: ${BASE_IMAGE}" echo "" echo "Base Image를 먼저 빌드하세요:" if [ -n "${ACR_NAME}" ]; then echo " ./build-base.sh ${BASE_IMAGE_TAG} ${ACR_NAME} ${RESOURCE_GROUP}" else echo " ./build-base.sh ${BASE_IMAGE_TAG}" fi exit 1 fi # ACR 로그인 수행 if [ -n "${ACR_NAME}" ] && [ -n "${RESOURCE_GROUP}" ]; then echo "" acr_login "${ACR_NAME}" "${RESOURCE_GROUP}" echo "" fi # Docker 빌드 echo "🔨 Service Image 빌드 시작... (빠른 빌드 예상)" echo "명령어: docker build --build-arg BASE_IMAGE=\"${BASE_IMAGE}\" -t \"${FULL_IMAGE_NAME}\" -f \"${DOCKERFILE_PATH}\" \"${BUILD_CONTEXT}\"" docker build --build-arg BASE_IMAGE="${BASE_IMAGE}" -t "${FULL_IMAGE_NAME}" -f "${DOCKERFILE_PATH}" "${BUILD_CONTEXT}" if [ $? -eq 0 ]; then echo "✅ Service Image 빌드 완료!" echo "이미지명: ${FULL_IMAGE_NAME}" # 이미지 정보 표시 echo "" echo "📊 Service Image 정보:" docker images "${FULL_IMAGE_NAME}" --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}\t{{.CreatedAt}}" # latest 태그 추가 생성 if [ "${IMAGE_TAG}" != "latest" ] && [ -n "${REGISTRY}" ]; then echo "" echo "🏷️ latest 태그 생성 중..." docker tag "${FULL_IMAGE_NAME}" "${REGISTRY}/${IMAGE_NAME}:latest" echo "✅ latest 태그 생성 완료: ${REGISTRY}/${IMAGE_NAME}:latest" fi # ACR 푸시 if [ -n "${ACR_NAME}" ]; then echo "" echo "🚀 ACR에 Service Image 푸시 중..." echo "📤 푸시 중: ${FULL_IMAGE_NAME}" docker push "${FULL_IMAGE_NAME}" if [ $? -eq 0 ]; then echo "✅ Service Image 푸시 성공" if [ "${IMAGE_TAG}" != "latest" ]; then echo "📤 푸시 중: ${REGISTRY}/${IMAGE_NAME}:latest" docker push "${REGISTRY}/${IMAGE_NAME}:latest" if [ $? -eq 0 ]; then echo "✅ latest 태그 푸시 성공" fi fi else echo "❌ Service Image 푸시 실패" exit 1 fi fi echo "" echo "🎉 Service Image 빌드 완료!" echo "" echo "📋 완료된 작업:" echo " ✅ Service Image 빌드: ${FULL_IMAGE_NAME}" echo " ✅ 사용된 Base Image: ${BASE_IMAGE}" if [ "${IMAGE_TAG}" != "latest" ] && [ -n "${REGISTRY}" ]; then echo " ✅ latest 태그: ${REGISTRY}/${IMAGE_NAME}:latest" fi if [ -n "${ACR_NAME}" ]; then echo " ✅ ACR 푸시 완료" fi echo "" echo "🧪 테스트 명령어:" echo " docker run -p 8000:8000 ${FULL_IMAGE_NAME}" echo " curl http://localhost:8000/health" if [ -n "${ACR_NAME}" ]; then echo "" echo "🔍 ACR 이미지 확인:" echo " az acr repository show-tags --name ${ACR_NAME} --repository ${IMAGE_NAME}" fi else echo "❌ Service Image 빌드 실패!" exit 1 fi echo "" echo "🏁 Service Image 빌드 프로세스 완료 - $(date)"