Spring/[P] AI 챗봇 기반 맞춤형 레시피 서비스

[AWS ElasticBeanstalk/GitHub Action] CI/CD 구축 (1) 배포 스크립트 작성하기

alsruds 2024. 3. 12. 23:37

 

 

GitHub Action 은 대상 리포지토리 .github 내 yml 파일을 읽어 동작을 수행합니다

배포를 진행하기 위한 스크립트를 작성해봅시당 :-)

 

⭐ 리포지토리 파일의 Root 경로에 .github 파일 위치시키기 !!

 


 

[ 개발용 GitHub Action Script 작성하기 ]

 

📜 프로젝트 구조 미리 보기

 

0. main 브랜치 이외에 develop 브랜치가 따로 세팅되어 있어야 한다

 

1. build.gradle 설정 추가

...

// aws elastic beanstalk
jar {
	enabled = false
}

 

2. .github/workflows/dev_deploy.yml

🏠 가이드라인 https://github.com/actions/github-script

 

GitHub - actions/github-script: Write workflows scripting the GitHub API in JavaScript

Write workflows scripting the GitHub API in JavaScript - actions/github-script

github.com

 

name: Irecipe Dev CI/CD

on:
  pull_request:
    types: [closed]
  workflow_dispatch: # 수동 실행도 가능하도록 설정

jobs:
  build:
    runs-on: ubuntu-latest
    # develop 브랜치에 머지할 때, github action 동작
    if: github.event.pull_request.merged == true && github.event.pull_request.base.ref == 'develop'

    steps:
      # 코드 가져오기
      - name: Checkout
        uses: actions/checkout@v2

      # 프로젝트 버전에 맞는 Java 설치
      - name: Set up JDK 17
        uses: actions/setup-java@v3
        with:
          java-version: 17
          distribution: 'adopt'

      # AWS EB 업로드 시 yml 파일 생성
      - name: Make Application-dev.yml
        run: |
          cd ./src/main/resources
          touch ./application-dev.yml
          echo "${{ secrets.APPLICATION_DEV }}" > ./application-dev.yml

      # 권한 부여
      - name: Grant execute permission for gradlew
        run: chmod +x ./gradlew
        shell: bash

      # 빌드 시작
      - name: Build with Gradle
        run: ./gradlew clean build -x test
        shell: bash

      # 빌드 시점 시간 - 타임스탬프 기록
      - name: Get current time
        uses: 1466587594/get-current-time@v2
        id: current-time
        with:
          format: YYYY-MM-DDTHH-mm-ss
          utcOffset: "+09:00"

      # 시간 조회
      - name: Show Current Time
        run: echo "CurrentTime=$"
        shell: bash

      # 배포할 패키지 생성
      - name: Generate deployment package
        run: |
          mkdir -p deploy
          cp build/libs/*.jar deploy/application.jar
          cp Procfile deploy/Procfile
          cp -r .ebextensions_dev deploy/.ebextensions
          cp -r .platform deploy/.platform
          cd deploy && zip -r deploy.zip .

      # AWS EB 에 배포
      - name: Beanstalk Deploy
        uses: einaregilsson/beanstalk-deploy@v20
        with:
          aws_access_key: ${{ secrets.AWS_ACTION_ACCESS_KEY_ID }}
          aws_secret_key: ${{ secrets.AWS_ACTION_SECRET_ACCESS_KEY }}
          application_name: irecipe-dev
          environment_name: Irecipe-dev-env
          version_label: github-action-${{ steps.current-time.outputs.formattedTime }}
          region: ap-northeast-2
          deployment_package: deploy/deploy.zip
          wait_for_deployment: false

 

· Step 의 각 Name 은 마음대로 지어도 상관없다

· 노출되면 안되는 정보는 github secret 을 이용하여 환경 변수 처리하기 (ex. ${{ secrets.~~~ }} )

· Beanstalk Deploy 에서 application_name 과 environment_name 은 생성한 AWS EB 에서의 이름과 동일하게 작성하기 !

 

3. .ebextensions_dev/00-makeFiles.config

✔️ AWS EB 에 추가적인 설정을 알려주는 파일들의 폴더 : ebextensions

✔️ Docker 없이 단일 플랫폼으로 AWS EB 에 배포할 경우, 관련 설정 파일을 AWS EB 가 생성하는 EC2 의 어디에 위치시킬지 알려주는 파일 : makeFiles.config

files:
    "/sbin/appstart" :
        mode: "000755"
        owner: webapp
        group: webapp
        content: |
            #!/usr/bin/env bash
            JAR_PATH=/var/app/current/application.jar

            # run app
            killall java
            java -Dfile.encoding=UTF-8 -jar $JAR_PATH

 

4. .ebextensions_dev/01-set-timezone.config

commands:
  set_time_zone:
    command: ln -f -s /usr/share/zoneinfo/Asia/Seoul /etc/localtime

 

· AWS EB 는 서버 시간이 영국 시간으로 기본 설정되어 있으므로, 한국 시간으로 변경하기

 

5. .platform/nginx.conf

user                    nginx;
error_log               /var/log/nginx/error.log warn;
pid                     /var/run/nginx.pid;
worker_processes        auto;
worker_rlimit_nofile    33282;

events {
    use epoll;
    worker_connections  1024;
    multi_accept on;
}

http {
  include       /etc/nginx/mime.types;
  default_type  application/octet-stream;


  log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';

  include       conf.d/*.conf;

  map $http_upgrade $connection_upgrade {
      default     "upgrade";
  }

  upstream springboot {
    server 127.0.0.1:8080;
    keepalive 1024;
  }

  server {
      listen        80 default_server;
      listen        [::]:80 default_server;

      location / {
          proxy_pass          http://springboot;
          # CORS 관련 헤더 추가
          add_header 'Access-Control-Allow-Origin' '*';
          add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
          add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type';
          proxy_http_version  1.1;
          proxy_set_header    Connection          $connection_upgrade;
          proxy_set_header    Upgrade             $http_upgrade;

          proxy_set_header    Host                $host;
          proxy_set_header    X-Real-IP           $remote_addr;
          proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;
      }

      access_log    /var/log/nginx/access.log main;

      client_header_timeout 60;
      client_body_timeout   60;
      keepalive_timeout     60;
      gzip                  off;
      gzip_comp_level       4;

      # Include the Elastic Beanstalk generated locations
      include conf.d/elasticbeanstalk/healthd.conf;
  }
}

 

· NGINX 서버로 리버스 프록시 설정해주기

 

6. Procfile

web: appstart

 

7. 스크립트 준비 끝 - ! 🌞