Python 도커 이미지 용량 최적화

우기·2024년 5월 1일
1
post-thumbnail

숏캡에서는 요약을 위한 모듈을 파이썬으로 구현해 사용하고 있다.
배포의 용이성을 위해 도커 이미지로 만들어 배포하고 있는데, 이미지 용량이 자그마치 1.24GB이다.

용랑 때문에 빌드 후 서버에서 pull시 매우 오래 걸리는 문제가 생겼다.

1. slim 이미지 사용


해당 문제를 인식은 하고 있었으나... 갈피를 잡지 못하고 있던 그 때...

소프트웨어 공학 시험에 도커 관련 문제가 나왔다.

python:3.10-slim
여기서 말하는 slim이란?


slim이란 단어를 보고 "경량화된 버전"으로 적었고, 집에 와서 검색하니 비슷한 의미였다.
  • docker 이미지는 용량 최적화를 위해 컨테이너 실행에 필요한 최소한의 파일만 들어있는 slim 이미지를 지원하고 있다

  • 용량이 작은 이미지를 사용할 때는 외부 패키지를 설치할 때 필요한 의존성 파일들이 존재하지 않아 에러가 발생할 수 있음
    출처: https://sw-ing.tistory.com/165 [끄느토리:티스토리]


이것을 기반으로 Dockerfile를 수정했다.

#FROM python:3.10-slim
# FROM python:3.10 # 기존의 도커 파일
WORKDIR /code
COPY requirements.txt .
COPY main.py .
COPY /dto ./dto
COPY /env ./env
COPY /resources ./resources
COPY /utils ./utils
COPY /audios ./audios
RUN pip install -r requirements.txt
CMD ["python","main.py"]

slim 이미지로 빌드를 하니 약 375.31MB로 줄었다.

2. Multi-Stage 빌드

multi stage build는 하나의 Dockerfile 내 여러 단계로 구성 된 이미지를 생성 하는 기능이다. 각 단계별로 필요한 파일만을 포함시키기 때문에 최종 사용되는 이미지의 크기를 줄일 수 있다.

예를 들면 이미지 생성 절차를

  • dependency 설치
  • 빌드
  • 배포

로 나눠 Dockerfile에 작성하면 배포에는 이전 과정의 결과만을 사용하므로 이미지의 크기를 줄일 수 있다.

FROM python:3.10-slim AS build

WORKDIR /code

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

FROM python:3.10-slim

WORKDIR /code

COPY --from=build /usr/local/lib/python3.10/site-packages /usr/local/lib/python3.10/site-packages
COPY main.py .
COPY dto ./dto
COPY env ./env
COPY resources ./resources
COPY utils ./utils
COPY audios ./audios

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

375.31MB 에서 326.05MB로 다시 한번 줄어든 것을 확인할 수 있다.

3.불필요한 의존성 제거

파이썬에서 필요한 모듈들을 기록해두는 requirements.txt 파일을 보니 내가 실제로 pip를 통해 설치한 것보다 훨씬 많은 모듈들이 기록돼있었다.
다른 글을 보니

https://stackoverflow.com/questions/25376213/delete-unused-packages-from-requirements-file
해당 글을 참고해 불필요한 의존성을 제거해봤다.

// 기존 29개
annotated-types==0.6.0
anyio==4.2.0
certifi==2023.11.17
charset-normalizer==3.3.2
colorama==0.4.6
decorator==4.4.2
distro==1.9.0
exceptiongroup==1.2.0
h11==0.14.0
httpcore==1.0.2
httpx==0.26.0
idna==3.6
imageio==2.34.0
imageio-ffmpeg==0.4.9
instaloader==4.10.3
moviepy==1.0.3
numpy==1.26.4
openai==1.9.0
pika==1.3.2
pillow==10.2.0
proglog==0.1.10
pydantic==2.5.3
pydantic_core==2.14.6
pytube==15.0.0
requests==2.31.0
sniffio==1.3.0
tqdm==4.66.1
typing_extensions==4.9.0
urllib3==2.1.0
// 5개
openai~=1.9.0
moviepy~=1.0.3
pytube~=15.0.0
instaloader~=4.10.3
pika~=1.3.2

하지만 위의 추가 모듈들은 openai, moviepy와 같은 모듈들이 의존성을 가지는 패키지기 때문에 실제 docker build를 하면 다시 설치되는 것을 확인했다.

다시 326MB...

결국 내가 할 수 있는 용량 최적화는 여기까지였다.
1.24GB => 326MB까지 용량을 줄였으니 그래도 큰 성과라고 생각한다.

마무리

몇 달 동안 이미지 크기가 크다는 생각만 하고 있었는데 이렇게 용량 최적화가 가능하다니..

지금까지는 도커를 단순한 툴 정도로만 생각해 Dockerfile을 인터넷에서 긁어오는 수준으로만 작성했다.

하지만 명령어의 순서에 따라 cache 사용 여부를 결정하거나 이미지에는 각 layer가 있는 등 공부할 것이 정말 많은 기술이라고 생각된다.

다음엔 도커 컨테이너 내부 구조에 대해 공부하고 스프링 이미지도 최적화하는 과정을 포스팅해봐야겠다.

profile
항상 한번 더 생각하는 개발자를 지향합니다!

0개의 댓글