Untitled

배경

: 기존에 사용하던 방식인 단일 인스턴스(EC2)에서 Nginx와 Docker-compose를 사용한 무중단배포 방식이 서버 메모리 문제로 사용 불가능 → 스케일 업을 하는 방법 혹은 스왑 메모리 활용 방법도 있으나, AutoScaling 기능을 간편하게 사용할 수 있는 Beanstalk으로 인프라 변경 결정

무중단배포 계획

1. 깃허브 레포지토리 dev, main 브랜치 Push / PR merge

2. 깃허브 액션의 Trigger 감지 → 코드를 Docker 이미지로 Build 한 뒤 , DockerHub로 push (Dockerfile)

3. Beanstalk로 배포 → docker-compose 파일을 통해, Docker Hub의 최신 버전 8080포트로 실행

설정 순서 및 방법

0. 디렉토리 구조

Untitled

1. 설정 파일

name: beans-docker

on:
  push:
    branches: [ "dev" ]
  pull_request:
    branches: [ "main", "dev" ]

jobs:
  CI-CD:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3
      - name: Set up JDK 17
        uses: actions/setup-java@v3
        with:
          java-version: '17'
          distribution: 'temurin'

      # gradle caching - 빌드 시간 향상
      - name: Gradle Caching
        uses: actions/cache@v3
        with:
          path: |
            ~/.gradle/caches
            ~/.gradle/wrapper
          key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
          restore-keys: |
            ${{ runner.os }}-gradle-

      - name: Grant execute permission for gradlew
        run: chmod +x ./gradlew

      - name: make env.properties
        if: |
          contains(github.ref, 'main') ||
          contains(github.ref, 'dev')  
        run: |
          touch env.properties
          echo "${{ secrets.ENV_PROPERTIES }}" > env.properties
        shell: bash

      - name: Build with Gradle
        run: ./gradlew build -x test

      # docker build & push
      # Dockerfile을 통해 이미지화
      # push to docker hub
      - name: Docker build & push to dev
        #        if: github.event_name == 'pull_request' && github.event.action == 'closed' && github.event.pull_request.merged == true
        if: |
          contains(github.ref, 'main') ||
          contains(github.ref, 'dev')  ||
          contains(github.ref, 'feat/beanstalk')
        run: |
          docker login -u ${{ secrets.DOCKER_EMAIL }} -p ${{ secrets.DOCKER_PASSWORD }}
          docker build -t ${{ secrets.DOCKER_USERNAME }}/moit . 
          docker push ${{ secrets.DOCKER_USERNAME }}/moit

  beanstalk:
    name: Deploy to EB
    runs-on: ubuntu-latest
    needs: [ CI-CD ]
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Get current time
        uses: gerred/actions/current-time@master
        id: current-time

      - name: Use current time
        env:
          TIME: "${{ steps.current-time.outputs.time }}"
        run: echo $TIME

      - name: Deploy to EB
        uses: einaregilsson/beanstalk-deploy@v21
        with:
          aws_access_key: ${{ secrets.AWS_ACCESS_KEY }}
          aws_secret_key: ${{ secrets.AWS_SECRET_KEY }}
          application_name: moit-docker
          environment_name: Moit-docker-env-1
          version_label: docker-${{ steps.current-time.outputs.time }}
          region: ap-northeast-2
          deployment_package: elasticbeanstalk/docker-compose.yml
          wait_for_environment_recovery: 180
version: "3.9"
services:
  backend:
    image: "moit03/moit:latest"  # docker-hub 레포지토리
    ports:
      - "80:8080"
    restart: "always"
FROM openjdk:17-alpine

COPY env.properties /env.properties

ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar

ENTRYPOINT ["java", "-jar", "/app.jar"]
# , "-Dspring.profiles.active=prod"

2. AWS Beanstalk (Docker) 설정

1) beanstalk 애플리케이션 생성

Untitled