멀티모듈 프로젝트 Docker 빌드 전략: Path 기반 접근법[Docker&Github Action]

2024. 12. 14. 15:45·Spring

0.1 멀티 모듈이란?

자바에서 모듈(Module)은 독립적으로 배포될 수 있는 코드의 단위를 말합니다.
멀티 모듈(Multi-Module)이란 이러한 코드 뭉치를 하나의 프로젝트 안에서 관리하는 것을 의미합니다.
멀티 모듈 안에서 각각의 모듈은 서로를 향한 의존성을 가질 수 있습니다.
여러개의 모듈을 생성할 때 반드시 멀티 모듈 프로젝트를 생성해야 하진 않지만 코드 중복 제거, 모듈 간 의존성을 위해 저장소에 배포하지 않아도 되는 점 등 장점이 있고 이를 각각 다른 컴포넌트로 구성해야 하는 경우에 하나의 프로젝트에서 어떻게 빌드를 수행해야 하는지 확인해 보겠습니다.

예시를 들자면 다음과 같이 스프링 프로젝트를 멀티모듈로 하나의 프로젝트에서 구성했습니다. 그 후에 컨테이너화 하여 서버에 각각의 컴포넌트로 띄우고자 합니다. 이제 다음으로 CI/CD과정을 통해서 Build를 수행하고자 한다면, 다른 github를 사용하는 대신 GithubAction의 Path전략을 사용할 수 있습니다. 

# 공통 베이스 이미지 설정
FROM amd64/amazoncorretto:21 AS base
WORKDIR /app

# 공통 빌드 인스트럭션
FROM base AS builder
ARG SERVICE_NAME

COPY ${SERVICE_NAME}/build/libs/*.jar app.jar

# 최종 이미지 설정
FROM amd64/amazoncorretto:21
COPY --from=builder /app/app.jar app.jar
ENTRYPOINT ["java", "-Duser.timezone=Asia/Seoul", "-jar", "-Dspring.profiles.active=docker", "app.jar"]

다음과 같이 최상위 폴더에 DockerFile을 생성해 줍니다. DockerFile의 키워드에 관련해서는 알고 계시다고 생각하고 간단하게만 설명하고 넘어가겠습니다. 
다음 코드는 이미지를 가져와서 공통으로 빌드를 수행할 수 있는 DockerFile입니다.
각 서비스 이름을 통해서 build를 수행할 수 있고, 그 후 이미지를 생성하는 코드입니다.

gradle을 사용한다면 다음과 같은 예시를 들 수 있겠습니다.

./gradlew :user-service:build -x test
docker build --build-arg SERVICE_NAME=user-service -t ${image Repository} .

다음과 같이 수행을 하게 된다면 멀티모듈로 구성된 서비스 이름으로 build가 이루어지게 됩니다. 

해당하는 모듈 이름을 통해 해당 모듈만 빌드를 수행할 수 있습니다. 

해당 프로젝트들을 여러 사람들이 작업하고 있고 각각의 작업물을 수행한 뒤 병합하는 과정에서 전체 application전체를 하나하나 다 build를 수행해야 한다면 모든 컴포넌트 build, 서버에 올리는 작업까지 너무 많은 시간이 걸리게 됩니다. 따라서 github에서는 path별로 수행할 수 있는 방법을 적용할 수 있습니다.

name: User Service CICD

on:
  push:
    branches: ["dev"]
    paths:
      - 'user-service/**'

다음은 github action의 yml파일입니다. github action을 수행하는 방법은 따로 설명드리지 않겠습니다.
다음과 같이 paths: 키워드를 작성하면 해당 path에 있는 파일이 변경되었을 때만 action파일을 수행할 수 있습니다.

예시로 다음과 같이 작성할 수 있습니다.

jobs:
  build_and_deploy:
    runs-on: ubuntu-22.04
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Set up JDK 21
        uses: actions/setup-java@v3
        with:
          distribution: 'corretto'
          java-version: '21'

      - name: Create application.yml
        run: |
          mkdir -p user-service/src/main/resources
          touch user-service/src/main/resources/application.yml
          echo "${{ secrets.USER_APPLICATION }}" > user-service/src/main/resources/application.yml
          cat user-service/src/main/resources/application.yml

      - name: Build User Service
        run: |
          ./gradlew :user-service:build -x test

      - name: Docker Login
        uses: docker/login-action@v2.2.0
        with:
          username: ${{ secrets.DOCKER_LOGIN_USERNAME }}
          password: ${{ secrets.DOCKER_LOGIN_ACCESSTOKEN }}

      - name: Docker Image Build and Push
        run: |
          docker build --build-arg SERVICE_NAME=user-service -t ${{ secrets.DOCKER_REPOSITORY }}/user-service-image .
          docker push ${{ secrets.DOCKER_REPOSITORY }}/user-service-image

      - name: Deploy User Service via SSH
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.SERVER_IP }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SERVER_KEY }}
          script: |
            cd ~
            ./deploy_user_service.sh
            docker image prune -f

여기서 주의 깊게 봐야 할 부분은

1. CI/CD를 수행할 때 1차적으로 path를 통해서 action을 수행하는가?

2. 그때 action 수행과정에서 해당 모듈만 build를 하는가?

입니다. 

따라서 해당내용을 확인하고 필요한 부분에만 따라서 build를 수행하고 배포하는 과정을 진행할 수 있습니다.

저작자표시 비영리 변경금지 (새창열림)

'Spring' 카테고리의 다른 글

Spring Boot 서비스 환경 스트레스 테스트 [Spring/Java]  (1) 2025.01.04
Spring Boot 프로파일링 및 Stress Test [Spring]  (0) 2024.12.21
가상 스레드 vs 반응형 프로그래밍 [Spring/Java]  (2) 2024.11.22
[Spring] 응? 이게 왜 롤백이 안되지? - 비동기와 @Transaction  (4) 2024.10.21
[Spring] Redis기반의 EventStreamListener가 동작하지 않는 문제  (2) 2024.10.15
'Spring' 카테고리의 다른 글
  • Spring Boot 서비스 환경 스트레스 테스트 [Spring/Java]
  • Spring Boot 프로파일링 및 Stress Test [Spring]
  • 가상 스레드 vs 반응형 프로그래밍 [Spring/Java]
  • [Spring] 응? 이게 왜 롤백이 안되지? - 비동기와 @Transaction
kiru98
kiru98
다양한 것들을 보고 직접 경험하는것을 중요시 합니다
  • kiru98
    기르기르
    kiru98
  • 전체
    오늘
    어제
    • 분류 전체보기 (30)
      • AI (4)
      • Project (1)
      • MLOps (1)
      • 데이터사이언스 (2)
      • Github (1)
      • Spring (17)
      • 알고리즘 (0)
      • DB (4)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    K6
    java
    spring boot
    Prometheus
    MLOps
    이미지생성
    StableDiffusion
    db
    Grafana
    redis
    PYTHON
    eventpublisher
    redis stream
    springboot
    AI
    spring
    Docker
    I2I
    GAN
    docker compose
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
kiru98
멀티모듈 프로젝트 Docker 빌드 전략: Path 기반 접근법[Docker&Github Action]
상단으로

티스토리툴바