해당 포스트 내용은 엘튼 스톤맨의 "도커 교과서"를 읽고 이해한 내용을 바탕으로 작성하였습니다.
대부분의 프로그래밍 언어는 프로젝트를 빌드하기 위해 다양한 도구가 필요하다. 소프트웨어 프로젝트를 빌드하려면 개발 팀원이 모두 같은 도구들을 사용해야하고, 이를 관리해야 한다. 이러한 경우 빌드 툴들을 Dockerfile을 통해 이미지로 패키징하고, 프로젝트 패키징시 해당 이미지를 사용하여 간편하게 관리할 수 있다.
도커 빌드란 Dockerfile과 context(경로 혹은 url에 존재하는 파일들)를 바탕으로 이미지를 생성하는 것이다. 멀티 스테이지 빌드란 이러한 빌드가 여러 단계로 나뉘어져 적용된 것을 말한다.
멀티 스테이지 빌드는 빌드가 여러 단계로 나뉘는 빌드를 의미한다. 아래의 예시는 세 단계로 나뉜 멀티 스테이지 빌드의 예시이다.
FROM base-image as build-stage #stage1
RUN echo 'building...' > /build.txt
FROM base-image as test-stage #stage2
COPY --from=build-stage /build.txt /build.txt
RUN echo 'testing...' > /build.txt
FROM base-image(런타임 환경 이미지) #stage3
COPY --from=test-stage /build.txt /build.txt
CAT cat /build.txt
각 빌드의 단계는 FROM 인스트럭션으로 부터 시작된다. 첫번째 스테이지는 빌드 스테이지이다. 이 스테이지에서는 빌드 도구가 설치된 기반 이미지를 사용하여 로컬 컴퓨터에서 작성된 코드를 바이너리 코드로 컴파일하고 빌드한다. 그리고 다음 스테이지인 테스트 스테이지에서는 작성된 소스코드를 가져와 다시 컴파일 하지 않고 발드한 바이너리 코드만 복사해 간다음 단위 테스트를 실행한다. 마지막 단계는 실행할 런타임이 들어있는 기반 이미지로 사용하여 빌드, 테스트가 완료된 애플리케이션을 이미지에 복사하여 실행시킨다.
이와 같은 멀티 스테이지 빌드를 사용하여 스테이지 별로 목적을 분리하고 애플리케이션의 이식성을 확보할 수 있다. 또한 빌드 도구를 도커 이미지로 관리하여 개발 환경을 중앙 집중적으로 관리할 수 있다. 팀 공통의 설정에서 벗어날 가능성을 원천적으로 차단하며 새로 팀에 합류하는 개발자도 빠르게 개발 환경을 갖출 수 있다.
FROM maven as builder
WORKDIR /usr/src/project
COPY pom.xml .
RUN mvn -B dependency:go-offline
COPY . .
RUN mvn package
#app
FROM openjdk
WORKDIR /app
COPY --from=builder /usr/src/project/target/project-service-0.1.0.jar .
EXPOSE 80
ENTRYPOINT ["java", "-jar", "/app/project-service-0.1.0.jar"]
실제 자바 소스코드를 빌드하고 실행하는 예제이다. 2개의 FROM이 사용된 멀티 스테이지 빌드가 적용된 스크립트이다. Dockerfile에 작성된 인스트럭션들을 따라가며 해설해보자.
이와 같이 하나의 Dockerfile에 여러 빌드 스테이지로 나누어 이미지를 생성할 수 있다. 다만 주의할 점은 생성되는 이미지에 포함되는 것은 마지막 FROM으로 생성된 이미지이다. 즉, 앞 스테이지에서 사용한 메이븐 빌드 도구는 포함되지 않는다. 만약 이미지에 이전 스테이지의 콘텐츠를 포함하고 싶다면 마지막 빌드 스테이지에 명시하여 해당 콘텐츠를 복사해 와야 한다.