본문 바로가기
docker

[Docker] 멀티 스테이지 를 이용하여 Dockerfile 빌드하기

by devjh 2021. 5. 27.
반응형

1. 멀티스테이지란

애플리케이션을 빌드하려면 많은 의존성 패키지 및 라이브러리가 필요합니다.

그러나 실행을 위한 환경에서는 빌드하기위한 라이브러리, 패키지 등이 필요 없는 경우가 많습니다.

그럴 경우 멀티 스테이지를 사용하면 최종적으로 생성되는 이미지에 불필요한 패키지들을 제거해 이미지 자체의 용량이 커지는것을 막을 수 있습니다.

 

예제를 통해 확인해보겠습니다.

2.  멀티스테이지를 사용하지 않는경우

golang을 빌드하여 실행하는 이미지를 만들어보겠습니다.

golang을 전혀 몰라도 상관없습니다. hello world만 찍을껍니다.

(1) main.go

//main.go
package main

import "fmt"

func main(){
	fmt.Println("hello world") 
}

(2) dockerfile

# Dockerfile
FROM golang:latest

ADD ./main.go /temp/

WORKDIR /temp

RUN go build -o myApp main.go

CMD "./myApp"

(3) 결과확인

$ docker build -t ms:1 .
$ docker images
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
ms           1         3653bceb0e96   2 seconds ago   864MB

Golang을 이용하여 빌드하고 실행하여 helo world를 찍는 이미지지만 image의 용량이 864메가나 됩니다.
경량이미지인 Golang:alpine 으로 base이미지를 변경하여 줄여봅니다.

 

3. base이미지를 경량이미지로 선택

FROM golang:alpine3.10

ADD ./main.go /temp/

WORKDIR /temp

RUN go build -o myApp main.go

CMD "./myApp"

 

$ docker build -t ms:2 .
$ docker images
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
ms           2         06bf1f2af276   17 minutes ago   361MB
ms           1         3653bceb0e96   23 minutes ago   864MB

베이스 이미지 선택도 꾀나 중요합니다.

경량이미지인 Golang:alpine 으로 base 이미지를 변경하여 500 MB 가까이 줄였지만

아직도 hello world 찍는데 360MB나 사용해야 합니다.

 

4. 멀티스테이지 이용

ARG BUILD_IMAGE=golang:alpine3.10
ARG BASE_IMAGE=alpine:3.10

FROM ${BUILD_IMAGE} AS build

ADD ./main.go /temp/

WORKDIR /temp

RUN go build -o myApp main.go

FROM ${BASE_IMAGE}

COPY --from=build /temp /temp

WORKDIR /temp

CMD "./myApp"

 

$ docker build -t ms:3 .
$ docker images
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
ms           3         17c2b7152a83   5 seconds ago    7.59MB
ms           2         06bf1f2af276   21 minutes ago   361MB
ms           1         3653bceb0e96   26 minutes ago   864MB

사실 이 이미지는 7.59MB 짜리였습니다.

 

빌드할때 필요한 이미지를 실행할 때까지 들고가니 이미지가 커진거였습니다.

 

golang alpine을 이용해 빌드를 하고

빌드해서 나온 실행파일만 alpine 이미지에 넘겨주면

이미지의 크기를 확 줄일 수 있습니다.

 

이러한 방식을 멀티스테이지라고 부릅니다.

 

멀티스테이지는 FROM이 여러번 들어갑니다.

 

- ARG BUILD_IMAGE=golang:alpine3.10

ARG 명령어를 사용하여 이미지의 이름을 지정해주고,

 

- FROM ${BUILD_IMAGE} AS build

${BUILD_IMAGE} 방식으로 이미지를 불러오며 뒤에 AS [별칭] 을 지정해줍니다.

 

- COPY --from=build /temp /temp

다음 FROM 구문에서 사용할때 이전 이미지를 통해 나온 결과물를 가져오고싶다면

--from=build(AS build로 별칭을 지정했으므로) 를 붙여주시면 build image에서 나온 결과물을 가져갈 수 있습니다.

반응형

댓글