기타

[도커/Docker] multi-stage build란??

F12:) 2023. 8. 31. 21:47

나는 현재 진행하고 있는 두 개의 프로젝트에서 도커를 사용하고 있다.(당연하지만...ㅎ) 하지만, 도커를 사용하여 이미지를 만들면 환경설정이 따로 필요없이 구동할 수 있다는 매우 좋은 점이 있지만, 많은 기능들이 추가됨에 따라 이미지가 매우 무거워지는 것은 사실이다.

 

실제로, 2월 말부터 진행하는 졸업 프로젝트에서 만든 도커 이미지는 무려 4.5기가이다... 프로젝트 주제의 특성 때문에 인공지능 모델을 사용해야해서 그렇기도 하지만, 4.5기가면 무시할 수는 없는 수준이다.

 

심지어, 프로젝트에서 오디오 전처리를 해야하는데 오디오 전처리를 하다가 도중에 도커가 강제 종료되기도 한다.(메모리 부족으로 인해서 ㅠㅠ)  그래서 나는 이미지를 줄이는 작업을 많이 도전해왔다. 이미지를 줄이는 것만으로도 조금 더 쾌적하게 진행될 수 있기 때문이다.

 

우선, 했던 가장 첫번째는 도커 이미지를 작은 것을 쓰는 것이다. 개발 환경에서는 buster, 배포 환경에서는 slim이라는 말이 있다.(사실 없지만, 만들어낸거긴... 합니다....) 실제로, 내가 개발하는 곳에서는 많은 기능들이 들어있는 이미지로 실험해보는 것이 좋다. 하지만 배포환경은 다르다. 배포할 때는 최대한 가볍게하여, 무리없이 진행되어야하는 것을 목표로 한다.

 

이에 나는 도커파일에서 FROM을 통해 가져오는 이미지를 작게 하였다. 그렇게 해서도 물론 3~400메가정도 준 것으로 기억한다. 하지만 이것은 드라마틱하게 차이나는 수치는 아니었다.

 

그래서 다른 방법을 고민하던 중, 한 가지 방법이 나의 눈에 들어왔다.

 


Multi-Stage Build

multi stage란, stage를 여러개 두어 이미지를 빌드하는 과정이다. 조금 더 간단하게 설명해보자.

 

우리는 보통 도커파일을 작성할 때, Base 이미지에 개발 환경에 맞게 필요한 파일들을 설치해준다. 이후, 이 파일을 통해서 컨테이너를 build하고 실행하게 된다. 여기서의 문제점은 build를 하면서 실행(배포)에는 불필요한 파일들까지 따라오게 된다. 가령 빌드에만 필요한 파일이라던지.. 등등

 

 

그래서 multi-stage build(이하 msb)를 사용한다. 말 그대로 스테이지를 여러개 두는 것이다. 내가 적용한 스테이지는 총 2개이며 과정은 다음과 같다.

 

1. 첫 번째 스테이지에서는 개발에 필요한 파일들을 base 이미지에 설치한다.

2. 두 번째 스테이지에서는 새로운 base 이미지를 불러와, build한 이미지에서 필요한 부분만 COPY한다.

 

두번째가 핵심이다. 우리가 배포에 필요한 부분만 COPY하는 것이다. 실제로, 나의 Dockerfile을 통해서 확인해보자.

 


FROM python:3.8.17-slim-buster as builder # 가장 뒤에 as builder를 붙임으로써, build 이미지임을 명시하자.

WORKDIR /app

# COPY, RUN 등.. 설정에 필요한 파일들을 설치해준다.

#----------------------------------------------------

# 두 번째 스테이지: 배포 이미지 설정
FROM python:3.8.17-slim-buster

# 첫 번째 스테이지에서 설치한 필요한 패키지들 복사
# 여기서는 파이썬 라이브러리들을 복사해주었다.
COPY --from=builder /usr/local/lib/python3.8/site-packages /usr/local/lib/python3.8/site-packages

# 작업 디렉토리 설정
WORKDIR /app

EXPOSE 5001

CMD [ "python", "main.py"]

 

위와 같다. 스테이지는 가로선으로 구분하였으며, 각 도커파일에서는 마치 두 개의 도커파일을 작성하는 것처럼 작성하자.

 

 

 

이렇게 하고 build를 하게 되면 놀라운 일이 벌어진다...

 

무려 4.5GB였던 이미지가 무려 3.3GB가 되었다. 1.2GB나 줄었고, 이제 내 로컬에서는 무리없이 잘 돌아가게 되었다.

 

 

실제로는 빌드와 배포 이미지뿐만 아니라, 테스트와 같은 다른 과정들에서도 이러한 멀티 스테이지를 활용할 수 있다.