Multistage Build

EEEFFEE·2024년 1월 17일

docker

목록 보기
3/6

24.01.17 최초 작성

1. Multistage build

  • 이미시 생성 시 빌드/런타임 단계를 나눠 실행하는 것
  • 빌드/런타임 각각 필요한 툴이 다르고 이미지의 크기를 최대한 작게 설정하기 위해 multistage build수행
  • 컨테이너 실행 후 동작에 필요한 파일만 남김

2. 이미지 파일 slim화 기법

2.1 layer 수 줄이기

  • 개발 버전과 서비스 버전을 나눠서 관리
  • 서비스 버전에는 가급적 layer를 적게 만들기 (RUN 구문 줄이기)
  • 개발단계 예시
    • 빌드를 위한 기능 위주

# syntax=docker/dockerfile:1
FROM golang:1.16
WORKDIR /go/src/github.com/alexellis/href-counter/
COPY app.go ./
RUN go get -d -v golang.org/x/net/html \
&& CGO_ENABLED=0 go build -a -installsuffix cgo -o app .

  • 서비스 단계 예시
    • 개발단계에서 생성한 파일을 사용하기 위한 기능 위주

# syntax=docker/dockerfile:1
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY app ./
CMD ["./app"]


#!/bin/sh
echo Building alexellis2/href-counter:build

#href-counter 이미지 빌드
docker build -t alexellis2/href-counter:build . -f build.Dockerfile

#컨테이너 생성
docker container create --name extract alexellis2/href-counter:build

#컨테이너에 있는 실행파일 host로 복사
docker container cp extract:/go/src/github.com/alexellis/href-counter/app ./app

#컨테이너 삭제 (실행파일은 host에 남아있음)
docker container rm -f extract

echo Building alexellis2/href-counter:latest

#실행환경 빌드 (실행파일 들어감)
docker build --no-cache -t alexellis2/href-counter:latest .

#실행파일 삭제
rm ./app

2.2 Multistage Build

  • 서로 다른 이미지를 사용하고 각 단계의 파일들을 복사하는 것이 가능

# syntax=docker/dockerfile:1

# 빌드 실행 (0단계)
FROM golang:1.16
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 go build -a -installsuffix cgo -o app .

# 빌드한 실행파일 복사해옴 (1단계)
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=0 /go/src/github.com/alexellis/href-counter/app ./
CMD ["./app"]

2.2.1 이름 설정

  • FROM <~~> AS <설정할 이름> : 단계의 이름 설정

# syntax=docker/dockerfile:1

FROM golang:1.16 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 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"]

2.2.2 특정 단계까지만 실행


docker build --target builder -t my/counter:latest

2.2.3 이전 단계를 새 단계로 사용


# syntax=docker/dockerfile:1

# 빌드 환경 구축
FROM alpine:latest AS builder
RUN apk --no-cache add build-base

# 구축한 빌드 환경 기반으로 컴파일
FROM builder AS build1
COPY source1.cpp source.cpp
RUN g++ -o /binary source.cpp

# 구축한 빌드 환경 기반으로 컴파일
FROM builder AS build2
COPY source2.cpp source.cpp
RUN g++ -o /binary source.cpp

2.3 BUILDKIT

  • BUILDKIT은 지정한 단계와 다른 단계와의 의존성을 파악해 빌드

  • 기존의 build는 어떤 단계를 지정 시 앞선 단계롤 모두 실행함

  • DOCKER_BUILDKIT=1 docker build --no-cache -f Dockerfile --target stage2을 통해 실행


# syntax=docker/dockerfile:1
FROM ubuntu AS base
RUN echo "base"

FROM base AS stage1
RUN echo "stage1"

FROM base AS stage2
RUN echo "stage2"

0개의 댓글