부수적인 작업을 줄이기 위해 S3 bucket 으로 build file 을 일괄 관리하자.

 이전 프로젝트를 구성하기 위해서는 source code 를 로컬 환경에서 빌드해서 scp 명령어를 통해 업로드하는 방식이었다. 하지만 매번 소스 코드 수정이 있을 때마다 build → file upload → build file 실행 작업의 반복으로 인해 부수적인 작업에 리소스를 사용하는 것이 불편했다. 그리고 이후 scale out 환경을 구성하는 경우에는 이 부수 작업의 무한 굴레에 빠지기 때문에 앞으로의 작업을 위해 개선이 필요했다. 결국 github action 을 통해 소스 코드를 빌드하고 S3 bucket 에 일괄 관리하는 방식으로 변경했다. 

 

1. 개념 및 용어 정리

[1] 멀티 모듈(multi-module) ? 

 멀티 모듈 프로젝트는 상호 연결된 여러 개의 모듈로 구성된 프로젝트를 의미한다. 각 모듈은 전체 서비스의 구성요소로 동작하며 독립적으로 빌드할 수 있는 것이 특징이다. 멀티 모듈을 통한 장점은 아래와 같다.

  • 멀티 모듈을 통한 공통 코드 분리
    • 중복 코드에 관한 일관성 관리의 주체가 시스템이 되기 때문에 신뢰성이 높다.
    • 공통 코드가 수정,  별도의 빌드/배포 사이클이 필요하지 않다.

 

[2] Gradle 멀티 모듈 빌드 명령어

/**  ./gradlew [module name]:build  **/

./gradlew member:build

SPRING_ACTIVE_PROFILES=test ./gradlew member:build // property 별도로 설정하는 경우

 

 

[3] mysql 컨테이너 생성 시점 sql 실행 설정

도커 컨테이너를 통해 mysql server 구성할 때 실행할 sql 파일들을 directory로 감싸 /docker-entrypoint-initdb.d 디렉토리를

volumne mount 를 하면 컨테이너 생성 시점에 해당 sql 동작 설정이 가능하다. 

services:
  member-db:
    image: library/mysql:8.0
    container_name: member-db
    volumes:
      - ./db/mysql/init:/docker-entrypoint-initdb.d # here !

 

[4] multirun 설정

intellij 에서 Multirun plugins 을 설정하면 여러 애플리케이션을 한번에 실행할 수 있다.

 

2. 과정 정리

1. S3 bucket access key, private key 설정

  • IAM > 엑세스 관리 > 사용자 > 사용자 생성
  • 사용자 계정 클릭 > 보안 자격 증명 > 엑세스 키 만들기 > CLI 클릭

 

2. github repository 엑세스 키 등록

  • git repository > settings > Secrets and variables > Actions > New repository secret

 

3. github action script 구성 및 S3 bucket 에 전송

  • main 로 push / pull request 시에 github action 이 동작하도록 설정
  • 각 모듈을 build & zip 하여 S3 bucket 에 전송
name: Java CI with Gradle

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

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read

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

      # Configure Gradle for optimal use in GiHub Actions, including caching of downloaded dependencies.
      # See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md
      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0

      ## member
      - name: build modules
        run: SPRING_PROFILES_ACTIVE=local ./gradlew clean member:build conference:build front:build analysis:build

      - name: make directory
        run: mkdir tmp

      - name: move to tmp
        run: |
          mv ./member/build/libs/member-0.0.1-SNAPSHOT.jar ./tmp &&
          mv  ./conference/build/libs/conference-0.0.1-SNAPSHOT.jar ./tmp &&
          mv  ./analysis/build/libs/analysis-0.0.1-SNAPSHOT.jar ./tmp &&
          mv  ./front/build/libs/front-0.0.1-SNAPSHOT.jar ./tmp

      - name: deliver to aws s3
        env:
          AWS_ACCESS_KEY_ID: ${{secrets.S3_BUCKET_ACCESS_KEY}}
          AWS_SECRET_ACCESS_KEY: ${{secrets.S3_BUCKET_SECRET_KEY}}
        run: |
          aws s3 cp \
          --region ap-northeast-2 \
          --acl private ./tmp \
          s3://cooper-workshop-deployment-bucket/ \
          --recursive

 

Reference