[Java, Docker] gradlew ... did not complete successfully
문제:
docker build를 실행했는데 다음과 같은 에러가 발생하며 빌드가 되지 않았다.
// 에러 메시지
ERROR: failed to solve: process "/bin/sh -c ./gradlew clean bootJar" \
did not complete successfully: exit code: 127
// Dockerfile
FROM bellsoft/liberica-openjdk-alpine:17
WORKDIR /app
COPY . .
RUN ./gradlew clean bootJar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app/build/libs/myapp-0.0.1-SNAPSHOT.jar"]
원인 및 해결방법:
라인 엔딩 문제이다.
윈도우 -> CRLF (Carriage Return Line Feed)
리눅스 -> LF (Line Feed)
> 내가 작성한 Dockerfile의 이미지 bellsoft/liberica-openjdk-alpine:17 는 Alpine Linux를 기반으로 하고 있다.
Alpine Linux는 기본적으로 Unix/Linux 형식의 줄 바꿈인 LF 를 사용한다.
> 윈도우 노트북을 사용해서 gradlew은 CRLF 형식으로 되어있음
=> OS 이미지가 사용하는 줄바꿈 형식과 현재 프로젝트 내의 gradlew의 줄바꿈 형식의 불일치
이는 인텔리제이(다른 IDE는 모름ㅈㅅ) 오른쪽 하단 탭에서 변경할 수 있는데,
gradlew 파일의 라인 엔딩을 변경해야한다. 그리고 저장까지 해야함.
삽질한 이유:
Dockerfile의 라인 엔딩을 수정함;
참고:
🤔 gradlew 이란? 그리고 gradle이랑의 차이점은?
> gradlew은 로컬 시스템에 gradle이 없을 때 프로젝트를 빌드하기 위해 사용된다.
> gradle은 로컬 시스템에 이미 설치된 gradle을 실행할 때 사용된다. 따라서 프로젝트를 공유하거나 다른 컴퓨터에 빌드할 때 일관된 결과를 얻으려면 gradlew을 사용하는 것이 좋다.
🤔 gradlew의 라인 엔딩을 변경해서 커밋해두면 되는거 아님?
> 프로젝트를 윈도우OS에서 열면 gradlew이 자동으로 CRLF, 맥OS는 LF 형식으로 열리더라. (운영체제에 따라 자동 변환)
> 왜?
> Git이 파일을 체크아웃할 때 줄 바꿈 형식으로 자동으로 변환하도록 제어함.
> 어떻게?
> Git의 core.autocrlf 설정으로 다양한 환경에서의 호환성 문제를 최소화한다.
윈도우OS에서는 `core.autocrlf true` 가 default로 설정되어, Git이 저장소에서 파일을 체크아울할 때 자동으로 LF -> CRLF로 변환하고, 커밋할 때는 CRLF를 LF로 변환하도록 한다.
맥OS와 리눅스에서는 많은 경우 `core.autocrlf input` 로 설정되어, 파일을 커밋할 때 CRLF -> LF로 변환하고, 체크아웃할 때는 변환하지 않도록 한다. 그러나`core.autocrlf false`인 경우도 있어 줄 바꿈을 전혀 조작하지 않기도 한다.
> 각 파일 형식별 줄 바꿈 처리 방식을 명시적으로 정의할 수 있어?
> ㅇㅇ. 프로젝트에 `.gitattributes` 파일을 추가하면 됨. 그리고 다음과 같이 작성하겜
//예시: gradlew 파일의 줄바꿈이 항상 LF로 유지되도록 설정하기
* text=auto
gradlew text eol=lf