Skip to content

docker image build를 최적화하는 과정 #71

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
woo-yu opened this issue Mar 17, 2021 · 0 comments
Open

docker image build를 최적화하는 과정 #71

woo-yu opened this issue Mar 17, 2021 · 0 comments
Assignees
Labels
documentation Improvements or additions to documentation

Comments

@woo-yu
Copy link
Contributor

woo-yu commented Mar 17, 2021

docker image 생성시 기존의 방식

로컬에서 jar 생성 -> jar를 이용해 docker build로 이미지 생성

이번에는 jar를 참조만하는게 아니라 직접 build 과정까지 한번에 이루어지게끔 욕심내서 구성해보았으나,

FROM gradle:6.8.3-jdk11 AS builder
WORKDIR /app
COPY --chown=gradle:gradle ./ourdus-spring ./
RUN gradle build --no-daemon


FROM openjdk:11-jre-slim
EXPOSE 8080
ARG JAR_FILES=/app/build/libs/*.jar
COPY --from=builder ${JAR_FILES} Ourdus-springboot.jar
ENTRYPOINT [ "java", "-Dspring.profiles.active=dev", "-jar", "Ourdus-springboot.jar" ]

wsl에서는 잘 작동하는데, 개인용 free tier EC2에서는 build하다가 자꾸 뻗어버린다...
관련해서 찾아보니, gradle이 빌드할때마다 종속성을 다시 다 다운로드해서 그런 것이라 예상.

공식 문서들을 찾아보면 dockerfile 내에서는 build를 진행하지 않는데, 제대로 만들자면 기존의 jar만 참고하는 코드에서도 개선할 부분이 보인다.

(이전 파일)
FROM openjdk:11-jre-slim
WORKDIR /app
EXPOSE 8080
ARG JAR_FILES=/app/build/libs/*.jar
COPY --from=builder ${JAR_FILES} Ourdus-springboot.jar
ENTRYPOINT [ "java", "-Dspring.profiles.active=dev", "-jar", "Ourdus-springboot.jar" ]

자 그렇다면, 어디를 개선해야할까? Spring docsBaeldung를 참고해보자면

This works fine for most applications, but there are a couple of drawbacks.
First, we are using the fat jar created by Spring Boot. This can impact startup time, especially in a containerized environment. We can save startup time by adding the exploded contents of the jar file instead.
Second, Docker images are built in layers. The nature of Spring Boot fat jars causes all application code and 3rd party libraries to be put into a single layer. This means even when only a single line of code changes, the entire layer has to be rebuilt.
By exploding the jar before building, application code and 3rd party libraries each get their own layer. This allows us to take advantage of Docker's caching mechanism. Now, when one line of code is changed, only that corresponding layer needs to be rebuilt.

fat jar를 만들어 쓰면 컨테이너 시작시간도 느려지고, 코드 하나 바뀔때마다 rebuild해야하는 단점이 크다.
그래서 caching을 이용해 한 줄 변경시 해당 layer만 다시 빌드하게끔 만들어준다.

<<<< 수정필요
FROM openjdk:8-jdk-alpine
RUN addgroup -S spring && adduser -S spring -G spring
USER spring:spring
ARG DEPENDENCY=target/dependency
COPY ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY ${DEPENDENCY}/META-INF /app/META-INF
COPY ${DEPENDENCY}/BOOT-INF/classes /app
ENTRYPOINT ["java","-cp","app:app/lib/*","hello.Application"]


FROM adoptopenjdk:11-jre-hotspot as builder
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} application.jar
RUN java -Djarmode=layertools -jar application.jar extract

FROM adoptopenjdk:11-jre-hotspot
WORKDIR /app
EXPOSE 8080
COPY --from=builder dependencies/ ./
COPY --from=builder snapshot-dependencies/ ./
COPY --from=builder spring-boot-loader/ ./
COPY --from=builder application/ ./
ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"]

FROM openjdk:11-jre-slim


ARG JAR_FILES=/app/build/libs/*.jar
COPY ${JAR_FILES} Ourdus-springboot.jar
ENTRYPOINT [ "java", "-Dspring.profiles.active=dev", "-jar", "Ourdus-springboot.jar" ]
@woo-yu woo-yu added the documentation Improvements or additions to documentation label Mar 17, 2021
@woo-yu woo-yu self-assigned this Mar 17, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

No branches or pull requests

1 participant