SpringBoot 멀티모듈 MSA 에서의 Docker 빌드 문제

twonezero·2024년 10월 14일
0

진행 중인 MSA 프로젝트에서 각 서비스 모듈에 대해 Docker를 활용한 CI/CD 파이프라인을 구축하던 중 Docker 환경 구축에 관련된 몇 가지 문제를 겪었습니다. 이를 해결하는 과정을 공유하고자 합니다.

겪었던 문제

1. Docker 빌드 컨텍스트에서 모듈 참조 문제

프로젝트가 멀티모듈 구조로 되어 있어서, 서비스 모듈별로 Docker 이미지를 빌드할 때 각 서비스가 공통 모듈(common, security)을 의존하고 있었습니다. Docker 빌드 중 해당 모듈들을 컨텍스트에서 가져오지 못해 빌드가 실패하는 문제가 발생했습니다. 구체적으로 Gradle 빌드 단계에서 공통 모듈이 복사되지 않았기 때문에 Could not get unknown property 에러가 발생했습니다.

  • 문제 발생 시의 Dockefile
# Stage 1: Build the application
FROM gradle:8.10.1-jdk17 AS build

WORKDIR /app

COPY . /app

RUN ./gradlew clean build -x test

FROM openjdk:17-jdk-slim

COPY --from=build /app/auth/build/libs/*SNAPSHOT.jar /app.jar

# JAR 파일 실행
CMD ["java", "-jar", "/app.jar"]

해결

해당 문제를 해결하기 위해 Docker 이미지 빌드 시의 컨텍스트가 루트 모듈에서 시작하도록 지정해야 합니다.

  1. 단일 이미지 빌드 시 루트 모듈의 위치에서 터미널 명령어 실행
 docker build --build-arg FILE_DIRECTORY=. -f ./<모듈 이름>/Dockerfile -t my-app .
  1. 루트 모듈 위치에서 Docker-compose.yml 작성
version: '3.8'

services:
//... 중략
  auth:
    image: ${DOCKER_HUB_NAMESPACE}/glowgrow-auth
    container_name: auth
    ports:
      - "19099:19099"
    build:
      context: .
      dockerfile: ./auth/Dockerfile
      args:
        - FILE_DIRECTORY=.
    environment:
      - SPRING_PROFILES_ACTIVE=${SPRING_PROFILES_ACTIVE}
    depends_on:
      - eureka

//... 생략
  • 컨테이너에 대한 설명을 살펴 보면 build context 가 루트 모듈의 현재 위치에서 시작되고, args 를 통해 현재의 위치를 변수로 넘겨주고 있는 것을 볼 수 있습니다.

해당 변경에 따라 아래와 같이 Dockerfile 도 수정해야합니다.

# Stage 1: Build the application
FROM gradle:8.10.1-jdk17 AS build

WORKDIR /app

# ARG로 전달된 파일 디렉터리 설정
ARG FILE_DIRECTORY

# 파일 복사
COPY $FILE_DIRECTORY /app

# auth 모듈만 빌드
RUN ./gradlew :auth:clean :auth:build -x test --no-daemon

FROM openjdk:17-jdk-slim

COPY --from=build /app/auth/build/libs/*SNAPSHOT.jar /app.jar

# JAR 파일 실행
CMD ["java", "-jar", "/app.jar"]

루트 모듈에 존재하는 다른 모듈들에 대한 의존성과 gradle 을 참조하여, 해당 모듈을 Build 해줄 수 있었습니다.

2. Dockerfile 에서 gradlew 못 찾는 문제

위 문제가 있기 전 사소하지만, 시간을 많이 잡아먹은 문제가 하나 있었습니다.
해당 문제를 해결하기 전, 아까 위의 Dockerfile 을 실행해보면 아래와 같이 에러를 볼 수 있습니다.

내용만 보면 gradlew 에 대한 권한문제가 있거나, 애초에 gradlew 파일이 없다고 생각할 수 있습니다. 하지만, 검색 후 단순히 개행 문제였던 것을 알 수 있습니다.

저는 윈도우 노트북을 사용하고 있어, 인텔리제이의 개행 형식도 CRLF 로 되어 있었습니다.
그런데 같은 프로젝트를 진행 중인 팀원들은 모두 Mac OS 를 사용하고 있어 저한테만 에러가 발생했던 것입니다.

해결

단순히 인텔리제이에서 gradlew 을 열어 CRLF 를 LF 로 변경만 하면 끝입니다. (매우 허무함)

profile
소소한 행복을 즐기는 백엔드 개발자입니다😉

0개의 댓글