From 578d78765e7d609c419ed7c772b0e584c3502640 Mon Sep 17 00:00:00 2001 From: pizzazoa Date: Fri, 11 Sep 2026 00:36:08 +0900 Subject: [PATCH] =?UTF-8?q?chore:=20=EC=9A=B4=EC=98=81=20EC2=20ARM64=20?= =?UTF-8?q?=EB=B0=B0=ED=8F=AC=20=EC=A4=80=EB=B9=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../workflows/deploy-to-prod-ec2-docker.yml | 40 ++++++++- .github/workflows/deploy-to-prod-ec2.yml | 88 ------------------- 2 files changed, 36 insertions(+), 92 deletions(-) delete mode 100644 .github/workflows/deploy-to-prod-ec2.yml diff --git a/.github/workflows/deploy-to-prod-ec2-docker.yml b/.github/workflows/deploy-to-prod-ec2-docker.yml index a003c2ca..f03fa6ea 100644 --- a/.github/workflows/deploy-to-prod-ec2-docker.yml +++ b/.github/workflows/deploy-to-prod-ec2-docker.yml @@ -3,15 +3,31 @@ name: Deploy to Prod (EC2 Docker Compose via GHCR) on: push: branches: [ main ] - workflow_dispatch: {} + workflow_dispatch: + inputs: + deploy_mode: + description: 앱을 배포하거나 이전 검증을 위해 이미지만 빌드·업로드합니다 + type: choice + required: true + default: full + options: + - full + - image-only + +concurrency: + group: saerok-prod-deploy + cancel-in-progress: false jobs: deploy: + if: ${{ github.event_name == 'workflow_dispatch' || vars.PROD_ARM64_AUTODEPLOY == 'true' }} runs-on: ubuntu-latest permissions: contents: read packages: write environment: prod + env: + DEPLOY_MODE: ${{ inputs.deploy_mode || 'full' }} steps: - name: Checkout @@ -21,6 +37,11 @@ jobs: id: normalize run: echo "image_repo=ghcr.io/${GITHUB_REPOSITORY,,}" >> "$GITHUB_OUTPUT" + - name: Set up ARM64 emulation + uses: docker/setup-qemu-action@v3 + with: + platforms: arm64 + - name: Set up Buildx uses: docker/setup-buildx-action@v3 @@ -37,8 +58,9 @@ jobs: with: images: ${{ steps.normalize.outputs.image_repo }} tags: | - type=raw,value=prod-latest - type=sha,format=long,prefix=prod- + type=raw,value=prod-latest,enable=${{ env.DEPLOY_MODE == 'full' }} + type=sha,format=long,prefix=prod-,enable=${{ env.DEPLOY_MODE == 'full' }} + type=raw,value=migration-${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }},enable=${{ env.DEPLOY_MODE == 'image-only' }} - name: Build & Push (BE image) id: build @@ -46,6 +68,7 @@ jobs: with: context: . file: ./Dockerfile + platforms: linux/amd64,linux/arm64 push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} @@ -53,6 +76,7 @@ jobs: cache-to: type=registry,ref=${{ steps.normalize.outputs.image_repo }}:buildcache,mode=max - name: Copy compose to EC2 + if: ${{ env.DEPLOY_MODE == 'full' }} uses: appleboy/scp-action@v0.1.7 with: host: ${{ secrets.EC2_HOST }} @@ -63,6 +87,7 @@ jobs: strip_components: 1 - name: Deploy on EC2 + if: ${{ env.DEPLOY_MODE == 'full' }} uses: appleboy/ssh-action@v1 with: host: ${{ secrets.EC2_HOST }} @@ -120,16 +145,22 @@ jobs: docker pull "$IMAGE_REF" # 이번 릴리스 digest를 사용해 재기동 - docker compose --env-file "$ENV_FILE" -f docker-compose.prod.yml up -d --force-recreate --quiet-pull app + docker compose --env-file "$ENV_FILE" -p saerok-prod -f docker-compose.yml -f docker-compose.prod.yml up -d --force-recreate --quiet-pull app echo "Waiting for BE /health..." + healthy=false for i in {1..40}; do if curl -fsS --max-time 2 http://127.0.0.1:8080/health >/dev/null; then echo "✅ BE is healthy" + healthy=true break fi echo "⏳ ($i/40)"; sleep 3 done + if [ "$healthy" != true ]; then + echo 'BE health check timed out' >&2 + exit 1 + fi docker image prune -af --filter "until=168h" || true docker builder prune -af --filter "until=168h" || true @@ -139,6 +170,7 @@ jobs: run: | { echo "## Prod deploy" + echo "- Mode: $DEPLOY_MODE" echo "- Image: ${{ steps.normalize.outputs.image_repo }}@${{ steps.build.outputs.digest }}" echo "- Commit: ${{ github.sha }}" echo "- Actor: ${{ github.actor }}" diff --git a/.github/workflows/deploy-to-prod-ec2.yml b/.github/workflows/deploy-to-prod-ec2.yml deleted file mode 100644 index 81c09bfd..00000000 --- a/.github/workflows/deploy-to-prod-ec2.yml +++ /dev/null @@ -1,88 +0,0 @@ -name: Deploy to Prod EC2 - -on: - workflow_dispatch: - -jobs: - deploy: - name: Build and Deploy to EC2 - runs-on: ubuntu-latest - environment: prod - - steps: - - name: Checkout source code - uses: actions/checkout@v3 - - - name: Set up JDK 21 - uses: actions/setup-java@v3 - with: - distribution: 'corretto' - java-version: '21' - - - name: Grant execute permission for Gradle - run: chmod +x gradlew - - - name: Fix Docker API compatibility for Testcontainers - run: echo 'api.version=1.44' > ~/.docker-java.properties - - - name: Build with Gradle - run: ./gradlew test bootJar - - - name: Copy JAR to EC2 - uses: appleboy/scp-action@v0.1.7 - with: - host: ${{ secrets.EC2_HOST }} - username: ubuntu - key: ${{ secrets.EC2_SSH_PRIVATE_KEY }} - source: build/libs/*.jar - target: ~/saerok/ - strip_components: '2' - - - name: Restart application on EC2 - uses: appleboy/ssh-action@v1 - with: - host: ${{ secrets.EC2_HOST }} - username: ubuntu - key: ${{ secrets.EC2_SSH_PRIVATE_KEY }} - debug: true - script: | - set -euxo pipefail - - cd ~/saerok - echo ">>> 현재 위치: $(pwd)" - echo ">>> 파일:" - ls -al - - # JAR 확인 - JAR_NAME=$(ls -1t *.jar | head -n1) - [ -n "$JAR_NAME" ] || { echo "❌ JAR 없음"; exit 2; } - echo ">>> 선택된 JAR: $JAR_NAME" - - # 기존 프로세스 종료 - pkill -f "$JAR_NAME" || true - - # 백그라운드 실행 - DB_URL="${{ secrets.DB_URL }}" \ - DB_USERNAME="${{ secrets.DB_USERNAME }}" \ - DB_PASSWORD="${{ secrets.DB_PASSWORD }}" \ - IAM_ACCESS_KEY="${{ secrets.IAM_ACCESS_KEY }}" \ - IAM_SECRET_KEY="${{ secrets.IAM_SECRET_KEY }}" \ - UPLOAD_IMAGE_BUCKET_NAME="${{ vars.UPLOAD_IMAGE_BUCKET_NAME }}" \ - UPLOAD_IMAGE_DOMAIN="${{ vars.UPLOAD_IMAGE_DOMAIN }}" \ - DEX_IMAGE_BUCKET_NAME="${{ vars.DEX_IMAGE_BUCKET_NAME }}" \ - DEX_IMAGE_DOMAIN="${{ vars.DEX_IMAGE_DOMAIN }}" \ - APPLE_CLIENT_ID="${{ secrets.APPLE_CLIENT_ID }}" \ - APPLE_TEAM_ID="${{ secrets.APPLE_TEAM_ID }}" \ - APPLE_KEY_ID="${{ secrets.APPLE_KEY_ID }}" \ - APPLE_PRIVATE_KEY="${{ secrets.APPLE_PRIVATE_KEY }}" \ - JWT_SECRET="${{ secrets.JWT_SECRET }}" \ - KAKAO_ADMIN_KEY="${{ secrets.KAKAO_ADMIN_KEY }}" \ - KAKAO_CLIENT_ID="${{ secrets.KAKAO_CLIENT_ID }}" \ - KAKAO_REDIRECT_URI="${{ secrets.KAKAO_REDIRECT_URI }}" \ - KAKAO_CLIENT_SECRET="${{ secrets.KAKAO_CLIENT_SECRET }}" \ - KMS_KEY_ID="${{ secrets.KMS_KEY_ID }}" \ - FIREBASE_ADMIN_KEY="${{ secrets.FIREBASE_ADMIN_KEY }}" \ - nohup java -Duser.timezone=Asia/Seoul -jar $JAR_NAME --spring.profiles.active=prod > app.log 2>&1 & - - echo "✅ 배포 완료" -