0. Multi Stage Build 란?
- 컨테이너 이미지를 만들면서 빌드에는 필요하지만, 최종 컨테이너 이미지에는 필요 없는 환경을 제거할 수 있도록 단계를 나누어 이미지를 만드는 방법입니다.

- 멀티 스테이지 빌드를 사용하면 실행 시에는 필요없는 파일 및 데이터들을 포함하지 않는 실행 파일을 만들 수 있어 경량화된 컨테이너를 만들 수 있습니다.
1. goapp.go 파일 생성
package main
import(
"fmt"
"time"
)
func main(){
for{
fmt.Println("Hello World")
time.Sleep(10 * time.Second)
}
}
2. golang 설치
-
Go언어 아카이브 파일 설치
wget https://golang.org/dl/go1.19.1.linux-amd64.tar.gz

-
압축해제
sudo tar -xzf [go1.19.1.linux-amd64.tar.gz](https://golang.org/dl/go1.19.1.linux-amd64.tar.gz) -C /usr/local
-
환경 변수 설정
-
환경 설정 파일 열기 : sudo nano /etc/profile
-
환경 변수 추가 : export PATH=$PATH:/usr/local/go/bin

-
변경 내용 적용 : source /etc/profile
-
버전 확인

3. go파일 실행
-
빌드

- 성공적으로 빌드를 마쳤다면, goapp 파일을 확인할 수 있습니다.
-
실행
- ./[build된 파일명]
- 예시 :
./gobuild

- goapp 파일이 잘 실행됬다면 10초마다 Hello World가 찍히는 것을 볼 수 있다.
4. Dockerfile 작성
-
nano Dockerfile
-
코드 작성
FROM golang:1.15-alpine3.12 AS gobuilder-stage
WORKDIR /usr/src/goapp
COPY goapp.go .
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /usr/local/bin/gostart
FROM scratch AS runtime-stage
COPY --from=gobuilder-stage /usr/local/bin/gostart /usr/local/bin/gostart
CMD ["/usr/local/bin/gostart"]

4. Dockerfile 빌드
- docker build -t [imageName:Tag][-f Docker 경로] .

- image 조회 :
docker images | grep goimage 
Multi Stage 장점
표준화
- 빌드 작업은 모두 Docker 컨테이너 내부에서만 실행되기 때문에, 동일한 Dockerfile만 있으면 사용자의 운영체제나 툴의 버전에 상관없이 동일한 환경을 구성할 수 있습니다.
- 실무에 적용하면, 신규 개발자의 적응 기간을 단축시키고, 빌드 서버 관리 부담이나 개발자 간 도구 버전 차이로 인한 빌드 실패를 줄일 수 있습니다.
성능 향상
- Dockerfile 빌드 시, 각 줄의 명령어(Instruction)를 실행하기 전에 캐시를 확인하여, 재사용할 수 있는 캐시가 있는지 확인합니다. 만약 명령어에 변경 사항이 있다면 이후의 모든 명령어가 다시 실행됩니다.
- Multi-Stage 파일 작성 시, 빌드 환경과 같이 변경되지 않는 파일들을 초기 단계에 배치하면 캐시를 90% 이상 사용할 수 있어 빌드 시간을 크게 절약할 수 있습니다.
경량화
- Dockerfile 스크립트를 통해 빌드 과정을 세밀하게 조정하여 최종 산출물인 이미지를 가능한 작게 유지할 수 있습니다.
- 특히 컴파일러 언어(C, Go)의 경우, 빌드 단계에서 많은 도구가 필요하지만, 이러한 도구들은 실행 파일에 포함될 필요가 없습니다. Multi-Stage를 사용하여 필요한 도구는 빌드 과정에서만 사용하고, 최종 산출물에는 실행 파일만 포함시킨다면 이미지의 경량화를 실현할 수 있습니다.