Multi-Module Deployment to AWS ECR and EC2 #149
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Multi-Module Deployment to AWS ECR and EC2 | |
on: | |
workflow_dispatch: | |
inputs: | |
profile: | |
description: '프로파일을 선택하세요 (dev 또는 prod)' | |
required: true | |
default: 'dev' | |
type: choice | |
options: | |
- dev | |
- prod | |
package: | |
description: '배포할 패키지를 선택하세요' | |
required: true | |
default: 'peauty-customer-api' | |
type: choice | |
options: | |
- customer | |
- designer | |
permissions: | |
contents: read | |
jobs: | |
deploy: | |
runs-on: ubuntu-latest | |
steps: | |
# 1. 코드 체크아웃 | |
- name: Checkout code | |
uses: actions/checkout@v3 | |
# 2. 환경 변수 설정 | |
- name: Set environment variables | |
run: | | |
echo "DEPLOY_PROFILE=${{ github.event.inputs.profile }}" >> $GITHUB_ENV | |
echo "DEPLOY_DOMAIN=${{ github.event.inputs.package }}" >> $GITHUB_ENV | |
echo "TARGET_PACKAGE=peauty-${{ github.event.inputs.package }}-api" >> $GITHUB_ENV | |
# 프로파일과 패키지에 따라 호스트와 사용자 설정 | |
if [[ "${{ github.event.inputs.profile }}" == "prod" && "${{ github.event.inputs.package }}" == "customer" ]]; then | |
echo "HOST_SECRET=EC2_CUSTOMER_PROD" >> $GITHUB_ENV | |
elif [[ "${{ github.event.inputs.profile }}" == "prod" && "${{ github.event.inputs.package }}" == "designer" ]]; then | |
echo "HOST_SECRET=EC2_DESIGNER_PROD" >> $GITHUB_ENV | |
elif [[ "${{ github.event.inputs.profile }}" == "dev" && "${{ github.event.inputs.package }}" == "customer" ]]; then | |
echo "HOST_SECRET=EC2_CUSTOMER_DEV" >> $GITHUB_ENV | |
elif [[ "${{ github.event.inputs.profile }}" == "dev" && "${{ github.event.inputs.package }}" == "designer" ]]; then | |
echo "HOST_SECRET=EC2_DESIGNER_DEV" >> $GITHUB_ENV | |
else | |
echo "Invalid profile or package selection" | |
exit 1 | |
fi | |
# 환경 변수 검증 | |
- name: Debug environment variables | |
run: | | |
echo "DEPLOY_PROFILE: $DEPLOY_PROFILE" | |
echo "DEPLOY_DOMAIN: $DEPLOY_DOMAIN" | |
echo "TARGET_PACKAGE: $TARGET_PACKAGE" | |
echo "HOST_SECRET: $HOST_SECRET" | |
# 2. Java 17 설치 | |
- name: Set up JDK 17 | |
uses: actions/setup-java@v3 | |
with: | |
java-version: '17' | |
distribution: 'corretto' | |
package: 'jdk' | |
jdk-version: '17.0.12' | |
# 3. 선택된 패키지 빌드 (로컬에서 JAR 생성) | |
- name: Build Selected Package | |
run: | | |
echo "Building $TARGET_PACKAGE with profile $DEPLOY_PROFILE..." | |
# 선택한 패키지 디렉토리로 이동 후 Gradle 빌드 | |
# $TARGET_PACKAGE-$DEPLOY_PROFILE => profile 이름이 customer-prod라서 | |
./gradlew clean build -Pspring.profiles.active=$TARGET_DOMAIN-$DEPLOY_PROFILE -p $TARGET_PACKAGE | |
# 4-1. ECR 자격 증명 | |
- name: Configure AWS credentials | |
uses: aws-actions/configure-aws-credentials@v3 | |
with: | |
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
aws-region: ap-northeast-2 | |
# 4-2. ECR 로그인 | |
- name: Log in to Amazon ECR | |
id: ecr-login | |
uses: aws-actions/amazon-ecr-login@v2 | |
# 5. Docker 이미지 빌드 및 푸시 | |
- name: Build and Push Docker Image to ECR | |
env: | |
ECR_REGISTRY: ${{ steps.ecr-login.outputs.registry }} | |
ECR_REPOSITORY: peauty/server | |
IMAGE_TAG: ${{ env.DEPLOY_PROFILE }} | |
run: | | |
echo "Building Docker image for $TARGET_PACKAGE with profile $DEPLOY_PROFILE..." | |
docker build -t $ECR_REPOSITORY:$IMAGE_TAG -f $TARGET_PACKAGE/Dockerfile $TARGET_PACKAGE | |
docker tag $ECR_REPOSITORY:$IMAGE_TAG $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG | |
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG | |
# 6. EC2 서버에 배포 | |
- name: Deploy to EC2 Server | |
uses: appleboy/[email protected] | |
env: | |
DEPLOY_PROFILE: ${{ github.event.inputs.profile }} | |
DEPLOY_DOMAIN: ${{ github.event.inputs.package }} | |
TARGET_PACKAGE: peauty-${{ github.event.inputs.package }}-api | |
ECR_REGISTRY: ${{ steps.ecr-login.outputs.registry }} | |
ECR_REPOSITORY: peauty/server | |
IMAGE_TAG: ${{ env.DEPLOY_PROFILE }} | |
with: | |
host: ${{ secrets[env.HOST_SECRET] }} | |
username: ${{ secrets.EC2_USER }} | |
key: ${{ secrets.EC2_SSH_KEY }} | |
envs: DEPLOY_PROFILE,DEPLOY_DOMAIN,TARGET_PACKAGE,ECR_REGISTRY,ECR_REPOSITORY,IMAGE_TAG | |
script: | | |
echo "Deploying to EC2 for $TARGET_PACKAGE with profile $DEPLOY_PROFILE" | |
# AWS CLI 설정 | |
aws configure set aws_access_key_id ${{ secrets.AWS_ACCESS_KEY_ID }} | |
aws configure set aws_secret_access_key ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
aws configure set region ap-northeast-2 | |
# Docker 이미지 Pull | |
aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin $ECR_REGISTRY | |
docker pull $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG | |
# 기존 컨테이너 중지 및 삭제 | |
echo "Docker Container Status" | |
docker ps | |
echo "STOP $DEPLOY_DOMAIN-$DEPLOY_PROFILE" | |
docker stop $DEPLOY_DOMAIN-$DEPLOY_PROFILE || { echo "Failed to stop container"; } | |
docker rm $DEPLOY_DOMAIN-$DEPLOY_PROFILE || { echo "Failed to remove container"; } | |
# 새로운 컨테이너 실행 | |
docker run --env-file ./.env -d -p 8080:8080 --name $DEPLOY_DOMAIN-$DEPLOY_PROFILE \ | |
--env SPRING_PROFILES_ACTIVE=$DEPLOY_DOMAIN-$DEPLOY_PROFILE \ | |
$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG | |
# 새로운 컨테이너 상태 확인 | |
echo "=== Verifying the new container ===" | |
sleep 10 # 컨테이너 초기화를 위한 대기 시간 | |
if ! docker ps --filter "name=$DEPLOY_DOMAIN-$DEPLOY_PROFILE" --filter "status=running" | grep $DEPLOY_DOMAIN-$DEPLOY_PROFILE; then | |
echo "새로운 컨테이너가 실행 중이지 않습니다. 로그를 확인하세요." | |
docker logs --tail 50 $DEPLOY_DOMAIN-$DEPLOY_PROFILE | |
exit 1 | |
fi | |
# 컨테이너 상태 확인 | |
docker ps |