사전 준비

스프링 부트로 프로젝트 생성한 뒤 깃헙 퍼블릭 저장소로 업로드합니다.

 

1. 호스트의 jar파일을 이미지에 추가하기

가장 간단한 방법입니다.

호스트 OS에서 빌드된 jar파일을 이미지에 추가합니다.

 

Dockerfile

FROM openjdk:11
LABEL topic="docker-test"
ARG JAR_FILE=./build/libs/*.jar   ## jar파일 변수 설정
ADD ${JAR_FILE} app.jar           ## 해당 파일을 이미지에 추가한다
ENTRYPOINT ["java", "-jar", "/app.jar"]    ## jar 실행

이미지 만들기

docker build -t {이미지명} {도커파일디렉터리)

저는 이미지 이름을 host-jar로 만들었습니다.

이미지가 정상적으로 생성됐는지 확인

docker images -f "label=topic=docker-test"

해당 이미지로 컨테이너 실행 및 확인

docker run -d -p 8081:8080 --name host-jar-container host-jar

docker ps
CONTAINER ID   IMAGE      COMMAND                CREATED          STATUS          PORTS                                       NAMES
f877b956190d   host-jar   "java -jar /app.jar"   11 seconds ago   Up 10 seconds   0.0.0.0:8081->8080/tcp, :::8081->8080/tcp   host-jar-container

 

 

http://localhost:8081 로 접속해서 다음과 같은 화면이 보이면 성공적으로 동작한 것입니다.

우선 이런식으로 이미지파일을 만드는 것은 권장하지 않습니다.

이유는 다음과 같습니다.

 

호스트OS에 산출물이 있어야합니다. (즉 빌드가 되어있어야합니다). 만일 애플리케이션에서 코드를 변경한다면 수동으로 계속 빌드하는 작업을 해줘야해줘야하는 단점이 있습니다.

 

 

 

2. 도커 이미지에서 빌드하기

위에서 호스트OS에서 빌드하는 작업을 이번엔 이미지를 만들 때 내부에서 자동화 처리 해보겠습니다.

 

Dockerfile

FROM openjdk:11
LABEL topic="docker-test"
RUN git clone https://github.com/brick0123/dummy.git # 깃허브에서 소스코드 clone
WORKDIR dummy  # dummy 디렉터리로 이동
RUN chmod 700 gradlew # 권한 변경 -rwx------
RUN ./gradlew clean build # 빌드 실행
ARG JAR_FILE=./build/libs/*.jar 
RUN cp ${JAR_FILE} /app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]

이미지 만들기

docker build -t internal-build .

이미지를 확인해보겠습니다.

정상적으로 이미지가 만들어졌지만, 아까 만든 이미지에 비해서 용량이 훨씬 더 큰 것을 확인할 수 있습니다.

이유는 도커 이미지를 만들때 내부에서 빌드함으로 불필요한 파일들 역시 이미지에 저장됩니다.

 

직접 눈으로 확인하기 위해 container로 실행하고 접속해봅시다.

docker run -d -p 8082:8080 --name internal-build-container internal-build
docker exec -it internal-build-container /bin/bash

 

우리가 필요한 것은 jar파일 하나인데 깃에서 받은 소스코드와 빌드 결과물이 다 이미지에 저장돼서 용량을 많이차지합니다.

 

3. 멀티스테이지

빌드 단계에서 불필요한 파일과, 최종적으로 컨테이너 필요한 환경을 분리하여 이미지 크기를 최적화 하는 방법입니다.

1번에서 했던 방법처럼 우리는 jdk를 설치하고 jar파일 하나만 필요한 상황입니다. 즉 최적화된 이미지 크기는 host-jar 이미지와 용량이 같아야 합니다. 

(Docker Engine 17.05 부터 지원됩니다)

 

Dockerfile

# build
FROM openjdk:11 as build # build라는 별칭 부여
RUN git clone https://github.com/brick0123/dummy.git
WORKDIR dummy
RUN chmod 700 gradlew
RUN ./gradlew clean build
ARG JAR_FILE=./build/libs/*.jar
RUN cp ${JAR_FILE} /app.jar

# run
FROM openjdk:11 
LABEL topic="docker-test"
ADD --from=build /app.jar /app.jar  # 빌드 결과물에서 /app.jar를 /app.jar로 추가한다.
ENTRYPOINT ["java", "-jar", "/app.jar"]

이미지 만들기

docker build -t multi-stage .

이미지 조회

자동화된 빌드를 실행함과 동시에 최적화된 이미지가 생성된 것을 확인할 수 있습니다.

 

컨테이너 종료 및 삭제

docker stop $(docker ps -q -f "label=topic=docker-test")
docker rm $(docker ps -aq -f "label=topic=docker-test")

이미지 삭제

docker rmi $(docker images -q -f "label=topic=docker-test")

 

Reference

 

컨테이너 인프라 환경 구축을 위한 쿠버네티스/도커 - 교보문고

컨테이너 인프라 환경을 이해하고 직접 구축해 보자! | 쿠버네티스와 도커를 활용한 컨테이너 인프라 환경 구축!컨테이너 인프라 환경을 지원하는 도구들을 유기적으로 연결해 설명한다쿠버네

www.kyobobook.co.kr

 

Spring Boot with Docker

this guide is designed to get you productive as quickly as possible and using the latest Spring project releases and techniques as recommended by the Spring team

spring.io