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