Docker Multi Stage란?

Docker Multi Stage란?

컨테이너 이미지를 만들면서 빌드 등에는 필요하지만 최종 컨테이너 이미지에는 필요 없는 환경을 제거할 수 있도록 단계를 나누어서 기반 이미지를 만드는 방법

Background

  • Docker가 등장한 이후 Docker Image를 작게 만들기 위한 노력들이 있었습니다.
    • Image가 작으면 작을 수록 빌드, 배포 시간이 짧아 지기 때문입니다.
  • 각각의 Instruction들은 Dockerfile 하나의 Layer로 추가가 되기 때문에 여러가지 최적화가 필요했습니다.
  • Docker Image를 가볍게 만들기 위해 나온 방법이 Multi Stage 방식입니다.

Multi Stage build 방식이 나오기 전에

  • builder-pattern을 활용했습니다.
    • 하나의 Dockerfile이 아닌 두 가지의 Dockerfile을 유지하는 것입니다.
  • Dockerfile.build
    • 여러 명령어를 실행하는 데 분리하지 않고 && \를 통해 하나의 Layer에서 처리할 수 있습니다.
    • 빌드를 위한 이미지 입니다.
FROM golang:1.7.3
WORKDIR /go/src/github.com/alexellis/href-counter/
COPY app.go .
RUN go get -d -v golang.org/x/net/html \ -> 하나의 Layer에서 명령어를 처리하기 위한 최적화
  && CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
  • Dockerfile
    • 어플리케이션을 실행하기 위한 Dockerfile입니다.
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY app .
CMD ["./app"]
  • build.sh
    • Multi stage를 지원하기 전에는 이렇게 따로 스크립트를 작성해야 했습니다.
#!/bin/sh
echo Building alexellis2/href-counter:build

# build image
docker build --build-arg https_proxy=$https_proxy --build-arg http_proxy=$http_proxy \
    -t alexellis2/href-counter:build . -f Dockerfile.build

docker container create --name extract alexellis2/href-counter:build
docker container cp extract:/go/src/github.com/alexellis/href-counter/app ./app
docker container rm -f extract

echo Building alexellis2/href-counter:latest

# run app
docker build --no-cache -t alexellis2/href-counter:latest .
rm ./app

Multi Stage가 등장하면서

  • 하나의 Dockerfile로 빌드 이미지와 실행 이미지를 분리할 수 있게 되어 훨씬 간편하게 이미지를 줄일 수 있게 되었습니다.
    • 뿐만 아니라 배포 이미지의 용량이 줄어 빌드 시간이 감소하게 되었습니다.
FROM golang:1.7.3 AS builder
WORKDIR /go/src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html
COPY app.go    .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .

FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /go/src/github.com/alexellis/href-counter/app .
CMD ["./app"]

Reference

0%