deploy-dev #127
This file contains hidden or 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: deploy-dev | |
| on: | |
| push: | |
| branches: | |
| - develop | |
| workflow_dispatch: | |
| inputs: | |
| tag: | |
| description: 'Optional explicit dev tag (default: dev-latest)' | |
| required: false | |
| default: 'dev-latest' | |
| concurrency: | |
| group: deploy-dev | |
| cancel-in-progress: true | |
| jobs: | |
| notify-failure: | |
| runs-on: ubuntu-latest | |
| needs: [build-deploy] | |
| if: failure() | |
| steps: | |
| - name: Notify deployment failure | |
| run: | | |
| echo "::error::배포 파이프라인 실패 (Build/Flyway/Docker/Deploy 중 하나). 워크플로우 로그를 확인하세요." | |
| echo "Flyway 마이그레이션 실패 시 이전 버전 앱이 계속 실행됩니다. SLACK_WEBHOOK_URL 시크릿을 설정하면 Slack 알림을 추가할 수 있습니다." | |
| build-deploy: | |
| runs-on: ubuntu-latest | |
| environment: dev | |
| permissions: | |
| id-token: write | |
| contents: read | |
| defaults: | |
| run: | |
| working-directory: ./ | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up JDK 21 | |
| uses: actions/setup-java@v4 | |
| with: | |
| java-version: '21' | |
| distribution: 'temurin' | |
| cache: 'gradle' | |
| - name: Grant execute permission for gradlew | |
| run: chmod +x gradlew | |
| - name: Set secret yml file | |
| run: | | |
| mkdir -p src/main/resources | |
| echo "${{ secrets.APPLICANT_SYNC_MAPPING_DATA }}" > src/main/resources/applicant-sync-mapping-data.yml | |
| find src | |
| # Additional Gradle Caches for better performance | |
| - name: Cache Gradle packages | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.gradle/caches | |
| ~/.gradle/wrapper | |
| key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} | |
| restore-keys: | | |
| ${{ runner.os }}-gradle- | |
| - name: Clean Build with Gradle (with Testing) | |
| env: | |
| JWT_ACCESS_KEY: ${{ secrets.JWT_ACCESS_KEY }} | |
| JWT_REFRESH_KEY: ${{ secrets.JWT_REFRESH_KEY }} | |
| GOOGLE_OAUTH_CLIENT_ID: ${{ secrets.GOOGLE_OAUTH_CLIENT_ID }} | |
| GOOGLE_OAUTH_CLIENT_SECRET: ${{ secrets.GOOGLE_OAUTH_CLIENT_SECRET }} | |
| GOOGLE_OAUTH_REDIRECT_URI: ${{ secrets.GOOGLE_OAUTH_REDIRECT_URI }} | |
| ALLOWED_REDIRECT_URI_LOCAL: ${{ vars.ALLOWED_REDIRECT_URI_LOCAL }} | |
| ALLOWED_REDIRECT_URI_DEV: ${{ vars.ALLOWED_REDIRECT_URI_DEV }} | |
| SWAGGER_OAUTH2_REDIRECT_URL: ${{ vars.SWAGGER_OAUTH2_REDIRECT_URL }} | |
| MAIL_STORAGE_S3_BUCKET: ${{ secrets.MAIL_STORAGE_S3_BUCKET }} | |
| MAIL_STORAGE_S3_REGION: ${{ secrets.MAIL_STORAGE_S3_REGION }} | |
| MAIL_STORAGE_S3_KEY_PREFIX: ${{ secrets.MAIL_STORAGE_S3_KEY_PREFIX }} | |
| run: | | |
| ./gradlew clean build --build-cache --parallel --daemon | |
| - name: Run Flyway migration | |
| env: | |
| DB_URL: ${{ secrets.DB_URL }} | |
| DB_USERNAME: ${{ secrets.DB_USERNAME }} | |
| DB_PASSWORD: ${{ secrets.DB_PASSWORD }} | |
| run: | | |
| if [ -z "$DB_URL" ] || [ -z "$DB_USERNAME" ] || [ -z "$DB_PASSWORD" ]; then | |
| echo "::error::DB_URL, DB_USERNAME, DB_PASSWORD 시크릿이 dev 환경에 설정되어 있는지 확인하세요." | |
| exit 1 | |
| fi | |
| ./gradlew flywayMigrate --no-daemon | |
| - name: Set up QEMU | |
| uses: docker/setup-qemu-action@v2 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| with: | |
| driver-opts: image=moby/buildkit:latest | |
| - name: Configure AWS credentials | |
| uses: aws-actions/configure-aws-credentials@v4 | |
| with: | |
| role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }} | |
| role-session-name: GithubActions-${{ github.run_id }} | |
| aws-region: us-east-1 | |
| - name: Login to Amazon ECR | |
| id: login-ecr-public | |
| uses: aws-actions/amazon-ecr-login@v2 | |
| with: | |
| registry-type: public | |
| - name: Cache Docker layers | |
| uses: actions/cache@v4 | |
| with: | |
| path: /tmp/.buildx-cache | |
| key: ${{ runner.os }}-buildx-${{ hashFiles('Dockerfile') }}-${{ github.sha }} | |
| restore-keys: | | |
| ${{ runner.os }}-buildx-${{ hashFiles('Dockerfile') }}- | |
| ${{ runner.os }}-buildx- | |
| - name: Build, tag, and push image to Amazon ECR | |
| env: | |
| ECR_REGISTRY: public.ecr.aws/${{ vars.ECR_PUBLIC_REGISTRY_ID }} | |
| ECR_REPOSITORY: yourssu/${{ vars.PROJECT_NAME }} | |
| run: | | |
| DEV_IMAGE_LATEST_TAG=dev-latest | |
| DEV_IMAGE_SHA_TAG=dev-${GITHUB_SHA} | |
| echo "ECR_REGISTRY=$ECR_REGISTRY" | |
| echo "ECR_REPOSITORY=$ECR_REPOSITORY" | |
| echo "FULL_IMAGE_NAME=$ECR_REGISTRY/$ECR_REPOSITORY:$DEV_IMAGE_LATEST_TAG" | |
| # create and use a new builder instance | |
| docker buildx create --use --name arm-builder | |
| docker buildx build \ | |
| --platform linux/arm64,linux/amd64 \ | |
| --push \ | |
| --provenance=false \ | |
| --cache-from "type=gha" \ | |
| --cache-from "type=local,src=/tmp/.buildx-cache" \ | |
| --cache-to "type=gha,mode=max" \ | |
| --cache-to "type=local,dest=/tmp/.buildx-cache-new,mode=max" \ | |
| -t $ECR_REGISTRY/$ECR_REPOSITORY:$DEV_IMAGE_SHA_TAG \ | |
| -t $ECR_REGISTRY/$ECR_REPOSITORY:$DEV_IMAGE_LATEST_TAG \ | |
| . | |
| # 캐시 교체 | |
| rm -rf /tmp/.buildx-cache | |
| mv /tmp/.buildx-cache-new /tmp/.buildx-cache | |
| - name: Deploy to AWS EC2 | |
| env: | |
| YOURSSU_PEM: ${{ secrets.YOURSSU_PEM }} | |
| HOST_URL: ${{ vars.HOST_URL }} | |
| SERVER_PORT: ${{ vars.SERVER_PORT }} | |
| CORS_ALLOWED_ORIGINS: ${{ vars.CORS_ALLOWED_ORIGINS }} | |
| DB_URL: ${{ secrets.DB_URL }} | |
| DB_USERNAME: ${{ secrets.DB_USERNAME }} | |
| DB_PASSWORD: ${{ secrets.DB_PASSWORD }} | |
| PROJECT_NAME: ${{ vars.PROJECT_NAME }} | |
| ENVIRONMENT: ${{ vars.ENVIRONMENT }} | |
| ECR_REGISTRY: public.ecr.aws/${{ vars.ECR_PUBLIC_REGISTRY_ID }} | |
| # For this project | |
| JWT_ACCESS_KEY: ${{ secrets.JWT_ACCESS_KEY }} | |
| JWT_REFRESH_KEY: ${{ secrets.JWT_REFRESH_KEY }} | |
| GOOGLE_OAUTH_CLIENT_ID: ${{ secrets.GOOGLE_OAUTH_CLIENT_ID }} | |
| GOOGLE_OAUTH_CLIENT_SECRET: ${{ secrets.GOOGLE_OAUTH_CLIENT_SECRET }} | |
| GOOGLE_OAUTH_REDIRECT_URI: ${{ secrets.GOOGLE_OAUTH_REDIRECT_URI }} | |
| ALLOWED_REDIRECT_URI_LOCAL: ${{ vars.ALLOWED_REDIRECT_URI_LOCAL }} | |
| ALLOWED_REDIRECT_URI_DEV: ${{ vars.ALLOWED_REDIRECT_URI_DEV }} | |
| SWAGGER_OAUTH2_REDIRECT_URL: ${{ vars.SWAGGER_OAUTH2_REDIRECT_URL }} | |
| MAIL_STORAGE_S3_BUCKET: ${{ secrets.MAIL_STORAGE_S3_BUCKET }} | |
| MAIL_STORAGE_S3_REGION: ${{ secrets.MAIL_STORAGE_S3_REGION }} | |
| MAIL_STORAGE_S3_KEY_PREFIX: ${{ secrets.MAIL_STORAGE_S3_KEY_PREFIX }} | |
| INPUT_DEPLOY_TAG: ${{ github.event.inputs.tag }} | |
| run: | | |
| mkdir -p ~/.ssh | |
| ssh-keyscan -H $HOST_URL >> ~/.ssh/known_hosts | |
| echo "$YOURSSU_PEM" > yourssu.pem | |
| chmod 600 yourssu.pem | |
| if [ -n "$INPUT_DEPLOY_TAG" ]; then | |
| DEPLOY_TAG="$INPUT_DEPLOY_TAG" | |
| else | |
| DEPLOY_TAG="dev-latest" | |
| fi | |
| # .env.dev 파일 생성 | |
| echo "SERVER_PORT=$SERVER_PORT" >> .env.dev | |
| echo "CORS_ALLOWED_ORIGINS=$CORS_ALLOWED_ORIGINS" >> .env.dev | |
| echo "DB_URL=$DB_URL" >> .env.dev | |
| echo "DB_USERNAME=$DB_USERNAME" >> .env.dev | |
| echo "DB_PASSWORD=$DB_PASSWORD" >> .env.dev | |
| echo "PROJECT_NAME=$PROJECT_NAME" >> .env.dev | |
| echo "ENVIRONMENT=$ENVIRONMENT" >> .env.dev | |
| echo "ECR_REGISTRY=$ECR_REGISTRY" >> .env.dev | |
| echo "JWT_ACCESS_KEY=$JWT_ACCESS_KEY" >> .env.dev | |
| echo "JWT_REFRESH_KEY=$JWT_REFRESH_KEY" >> .env.dev | |
| echo "GOOGLE_OAUTH_CLIENT_ID=$GOOGLE_OAUTH_CLIENT_ID" >> .env.dev | |
| echo "GOOGLE_OAUTH_CLIENT_SECRET=$GOOGLE_OAUTH_CLIENT_SECRET" >> .env.dev | |
| echo "GOOGLE_OAUTH_REDIRECT_URI=$GOOGLE_OAUTH_REDIRECT_URI" >> .env.dev | |
| echo "ALLOWED_REDIRECT_URI_LOCAL=$ALLOWED_REDIRECT_URI_LOCAL" >> .env.dev | |
| echo "ALLOWED_REDIRECT_URI_DEV=$ALLOWED_REDIRECT_URI_DEV" >> .env.dev | |
| echo "SWAGGER_OAUTH2_REDIRECT_URL=$SWAGGER_OAUTH2_REDIRECT_URL" >> .env.dev | |
| echo "MAIL_STORAGE_S3_BUCKET=$MAIL_STORAGE_S3_BUCKET" >> .env.dev | |
| echo "MAIL_STORAGE_S3_REGION=$MAIL_STORAGE_S3_REGION" >> .env.dev | |
| echo "MAIL_STORAGE_S3_KEY_PREFIX=$MAIL_STORAGE_S3_KEY_PREFIX" >> .env.dev | |
| echo "IMAGE_TAG=$DEPLOY_TAG" >> .env.dev | |
| # create deployment directory structure | |
| ssh -i yourssu.pem ubuntu@$HOST_URL "mkdir -p ~/$PROJECT_NAME-dev-api/logs" | |
| # deploy environment file and docker script to host machine | |
| scp -i yourssu.pem .env.dev ubuntu@$HOST_URL:~/$PROJECT_NAME-dev-api/ | |
| scp -i yourssu.pem scripts/docker-deploy.sh ubuntu@$HOST_URL:~/$PROJECT_NAME-dev-api/ | |
| # Make the script executable | |
| ssh -i yourssu.pem ubuntu@$HOST_URL "chmod +x ~/$PROJECT_NAME-dev-api/docker-deploy.sh" | |
| # Execute the script | |
| ssh -i yourssu.pem ubuntu@$HOST_URL "cd ~/$PROJECT_NAME-dev-api && \ | |
| PROJECT_NAME=$PROJECT_NAME IMAGE_TAG=$DEPLOY_TAG CONTAINER_SUFFIX=dev ENV_FILE=.env.dev ./docker-deploy.sh" |