본문 바로가기

Docker/Dockerfile

Dockerfile의 내용과 빌드 결과물 확인

# dockerfile이 실행될때 어떤 과정으로 이미지가 생성되는지 확인한다.

# 들어가기에 앞서 openjdk에 대해서 간단하게 알아본다.

JRE는 "Java Runtime Environment"의 약어로 Java 프로그램이 실행되도록 제공되는 환경이다.
여기에는 JVM, 클래스 라이브러리 및 기타 지원 파일이 들어 있다. 컴파일러, 디버거 등의 개발 도구는 포함되어 있지 않다 .

JDK는 "Java SE Development Kit"의 약어로 Java 애플리케이션을 개발하기 위해 필요한 프로그램 
(javac, java, javadoc, appletviewer, jdb, javap, rmic, …) 과 JRE가 포함되어 있다.

# java -Djarmode=layertools -jar api.jar extract 내용에 대해서 알아보자.

FROM openjdk:11-jre-slim
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/api.jar"]

위의 dockerfile의 내용처럼 작성을 해도 문제는 없다. 다만 jar파일이 커지면 커질수록 빌드 속도가 느려지게 되어 효율성이 떨어지게 된다. 그래서 jar파일을 4개의 레이어로 나누어 빌드를 하게되면 빌드 시간을 단축할 수 있다. 아래의 내용을 보자.

Docker는 layer를 활용하여 기존 layer가 local에 있으면 재사용하는 캐쉬방식으로 진행되어 
효율화를 이룬 아키텍처를 가지고 있는데, 위의 Dockerfile처럼 구성하면 Java의 모든 구조가 
jar 파일로 되는 것이기 때문에 layer를 재사용하기 어렵다. 
다시 말하면, 코드를 한 줄이라도 수정하게 되면 캐쉬 해놓은 layer를 사용할 수 없기 때문에 
다시 만드는 작업이 필요하게 된다.

이러한 문제를 해결하기 위해 layering feature를 사용한다. 
쉽게 말하면 하나로 이루어졌던 구조를 4개의 Layer로 나누고 변경이 적은 부분은 캐싱된 것을 사용하고, 
변경이 잦은 부분만을 새로 구축해 효율적으로 container image를 만들 수 있는 방법이다.

아래의 명령어가 그 역할을 한다고 볼 수 있다.
RUN java -Djarmode=layertools -jar api.jar extract

1.dockerfile내용

# 자바 애플맄이션이 실행되도록 환경을 openjdk11을 통해서 제공한다.
FROM adoptopenjdk/openjdk11 as builder

# 작업경로 설정
WORKDIR /

# 해당 경로의 모든 jar파일을 변수로 담는다. (예를들어 AWS Codecommit에 firstproject라는 폴더 밑에 libs라는 폴더가 있고
해당 경로에 aaa.jar, bbb.jar가 있다면 2개의 jar파일을 변수로 담아둔다.)
ARG JAR_FILE=build/libs/*.jar

# 빌드된 jar파일을 WORKDIR 경로인 / 로 이동함과 동시에 api.jar파일 이라는 이름으로 생성된다.
COPY ${JAR_FILE} /api.jar

# java의 빠른 빌드를 위해 레이어를 4개로 나누고 이미 빌드되도 캐싱된 부분은 제외하고 새롭게
변경된 부분만을 빌드한다. (빌드 시간을 단축할 수 있다.)
RUN java -Djarmode=layertools -jar api.jar extract

# 리소스 경로에 있는 entrypoint-dev.sh 파일을 docker image의 /경로로 entrypoint.sh이름으로 복사
COPY entrypoint-dev.sh /entrypoint.sh

# /entrypoint.sh 존재하는 파일의 권한을 755로 설정
RUN chmod 755 /entrypoint.sh

# /logs 폴더를 생성
RUN mkdir /logs

# touch 명렁어로 파일의 생성 시간 확인
RUN touch /logs/bcheck-app.log

# /tcp 9998 포트롤 활용하여 서비스 
EXPOSE 9998/tcp

# CMD와 비슷한 역할을 한다. 컨테이너가 생성되고 최초로 실행할때 수행되는 명령어를 입력한다.
# 컨테이너를 띄울때 jar파일이 실행되어 스프링 서버가 구동되도록 하는 역할 이다.
ENTRYPOINT ["sh", "entrypoint.sh"]

2. entrypoint-dev.sh 파일의 내용

#!/bin/bash

java -Dspring.profiles.active=dev -jar /api.jar

3. dockerfile의 최적화

최적화 방법도 여러가지가 존재 한다.
이 부분은 다음에 기회가 있을때 정리한다.
참고 사이트는 아래와 같다.
https://jonnung.dev/docker/2020/04/08/optimizing-docker-images/

 

조은우 개발 블로그

 

jonnung.dev

 

'Docker > Dockerfile' 카테고리의 다른 글

nginx를 활용한 dockerfile 빌드  (0) 2022.08.01