진행 중인 MSA 프로젝트에서 각 서비스 모듈에 대해 Docker를 활용한 CI/CD 파이프라인을 구축하던 중 Docker 환경 구축에 관련된 몇 가지 문제를 겪었습니다. 이를 해결하는 과정을 공유하고자 합니다.
프로젝트가 멀티모듈 구조로 되어 있어서, 서비스 모듈별로 Docker 이미지를 빌드할 때 각 서비스가 공통 모듈(common, security)을 의존하고 있었습니다. Docker 빌드 중 해당 모듈들을 컨텍스트에서 가져오지 못해 빌드가 실패하는 문제가 발생했습니다. 구체적으로 Gradle 빌드 단계에서 공통 모듈이 복사되지 않았기 때문에 Could not get unknown property 에러가 발생했습니다.
# 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 이미지 빌드 시의 컨텍스트가 루트 모듈에서 시작하도록 지정해야 합니다.
docker build --build-arg FILE_DIRECTORY=. -f ./<모듈 이름>/Dockerfile -t my-app .
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
//... 생략
해당 변경에 따라 아래와 같이 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 해줄 수 있었습니다.
위 문제가 있기 전 사소하지만, 시간을 많이 잡아먹은 문제가 하나 있었습니다.
해당 문제를 해결하기 전, 아까 위의 Dockerfile 을 실행해보면 아래와 같이 에러를 볼 수 있습니다.
내용만 보면 gradlew 에 대한 권한문제가 있거나, 애초에 gradlew 파일이 없다고 생각할 수 있습니다. 하지만, 검색 후 단순히 개행 문제였던 것을 알 수 있습니다.
- 참고 글
스택오버플로우
저는 윈도우 노트북을 사용하고 있어, 인텔리제이의 개행 형식도 CRLF 로 되어 있었습니다.
그런데 같은 프로젝트를 진행 중인 팀원들은 모두 Mac OS 를 사용하고 있어 저한테만 에러가 발생했던 것입니다.
단순히 인텔리제이에서 gradlew 을 열어 CRLF 를 LF 로 변경만 하면 끝입니다. (매우 허무함)