Docker에서 Multi Stage Build를 사용해보자

윤학·2023년 11월 15일
0

Docker

목록 보기
2/2
post-thumbnail

Docker 단일 파일 내에 FROM 명령어가 두개로 나누어져 있는것을 접하고 해당 개념이 Multi Stage Build라는 것을 알게 되어 정리하고자 한다.

Multi Stage Build 이전에 Builder Pattern을 간단히 알아야 하는데 실제 동작하는데 필요한 애플리케이션 이미지와 빌드에 필요한 이미지를 구분하여 실제 동작하는 이미지에서는 불필요한 파일들은 포함하지 않아 이미지의 크기를 작게 가져가는 방법이라고 알면 될 것 같다.

예전에는 이를 수행하기 위해 별도의 Docker 파일로 관리해야 했기에 관리 문제가 있었지만 Mulit Stage Build에서는 단일 Docker 파일에서 작성할 수 있기 때문에 관리면에서 나아졌다고 한다.

사용법

그럼 어떻게 사용할까?

일단 기존에 했던 방식으로 한번 빌드를 하고 크기가 얼마나 되는지 알아보자.

현재 로컬에 있는 파일들은 NestJS에서 프로젝트를 처음 생성해주는 명령을 수행한 이후 생성된 파일들로 구성되어 있다.

그리고 빌드까지 수행하여 간단하게 이미지를 생성해보자.

docker build --no-cache -t legacy-build:1.0 .

FROM node:20.9.0-alpine

COPY . .

RUN npm install

RUN npm i -g @nestjs/cli

RUN npm run build

그리고 Multi Stage Build를 수행해보자.

Docker 파일에서는 FROM 명령어로부터 각각 다른 base 이미지와 새로운 빌드 단계가 시작됨을 알리기에 일단 FROM 명령어가 2개가 있으면 될 것 같다.

FROM node:20.9.0-alpine as builder

WORKDIR /app

COPY ./package.json /app
COPY ./package-lock.json /app

RUN npm install

RUN npm i -g @nestjs/cli

COPY . .

RUN npm run build

FROM node:20.9.0-alpine

WORKDIR /app

COPY --from=builder /app/dist /app/dist
COPY --from=builder /app/node_modules /app/node_modules

처음 FROM 부터 RUN npm run build 까지의 명령어들을 통해 빌드된 결과물을 builder라고 이름을 정하고, 하단의 COPY --from=builder에서 애플리케이션을 구동시키기 위한 폴더들만 가져와 이미지의 크기를 줄이고 있다.

as builder처럼 별칭을 따로 작성하지 않으면 자동적으로 0부터 숫자가 부여되어 --from=0이라고 작성할 수 있습니다.

그럼 이렇게 이미지를 만들어보자.

docker build --no-cache -t multi-stage-build:1.0 .

그럼 기존 대비 이미지의 크기가 447MB -> 309MB로 줄어든 것을 볼 수 있다.

밑에 <'none'>에 해당하는 이미지는 빌드된 결과물을 가지고 있는 이미지이다.

어렵지 않게 이미지의 크기를 줄일 수 있기에 필요할 때는 해당 방법을 사용하는 것이 좋을 것 같다.

또한, 최신의 Docker 엔진에는 BuildKit 빌드 엔진을 통해 stage를 병렬로도 빌드할 수 있고, 여러 stage가 있더라도 사용되지 않는 stage는 알아서 빌드 과정에 포함시키지 않으니 추후 시도해볼 수 있을 것 같다.

참고

Multi-stage builds

profile
해결한 문제는 그때 기록하자

0개의 댓글