본문 바로가기
개발포스팅

[포스팅공유] 도커 이미지 잘 만드는 방법

by bzerome240 2022. 1. 18.

도커 이미지 관련하여 글을 보다가 이미지 잘 만드는 법 이라는 글을 보고 유용해보여서 공유하기!

 

 

조은우 개발 블로그

 

jonnung.dev

 

 

(1) 베이스 이미지는 사이즈가 작은 것을 선택

보통 Alpine 리눅스 도커 이미지 로 시작하는 것을 추천

단, python은 Debian Buster를 기반으로 한 python:3.8-buster 또는 3.8-slim-buster를 사용하는 것을 추천

 

(2) 이미지 레이어 개수를 줄이자

레이어는 RUN, ADD, COPY 명령문에서만 생성되기 때문에 아래와 같이 여러 개로 분리된 명령을 체이닝(chaining) 으로 엮어보자.

레이어 개수가 적다고 도커 이미지/컨테이너 성능에 영향을 주진 않지만 Dockerfile 가독성과 유지 보수 관점에서 도움이 될 것이다.

RUN apt-get update
RUN apt-get -y install git
RUN apt-get -y install locales
RUN apt-get -y install gcc

위 내용을 아래와 같이 단일 RUN 구문으로 체이닝 하면 기존 4개 레이어가 생성되는 것을 1개 레이어로 줄일 수 있다. 그리고 하는 김에 설치할 패키지 순서를 알파벳 순서로 정렬하면 가독성도 높고, 중복 설치를 방지할 수 있는 효과도 있다.

RUN apt-get update && apt-get install -y \
    gcc \
    git \
    locales

 

(3) 애플리케이션 코드를 복사하는 부분은 아래로

아래 샘플 Dockerfile에서는 COPY가 2번 실행된다.
첫번째는 의존성 패키지가 명시된 파일이고, 두번째는 애플리케이션 소스 코드가 저장된 디렉터리다.

FROM python:3.8-slim-buster

WORKDIR /usr/src/app

COPY requirements.txt /usr/src/app
COPY django_project /usr/src/app

RUN pip install -r requirement.txt

CMD ["pip", "freeze"]

보통 의존성 패키지는 자주 바뀌지 않기 때문에 첫번째 COPY 명령으로 생성된 레이어는 캐시 될 것이다.
하지만 두 번째 COPY는 빌드할 때마다 바뀔 수 있기 때문에 캐시가 자주 초기화될 것이고, 그 다음 실행될 RUN명령어에서 수행하는 의존성 패키지 설치가 매번 실행될 가능성이 높다.
이렇게 될 경우 불필요하게 빌드 시간이 늘어나고, 자칫 의존성 패키지 버전을 latest나 *로 해뒀다면 예기치 못하게 패키지 버전이 올라갈 수 있다.

따라서 애플리케이션 코드 복사 명령은 자주 변경되지 않는 명령문 다음에 오는 것이 이미지 빌드 시간을 단축하는 데 유리하다.

 

(4) 프로그래밍 언어마다 패키지 매니저가 제공하는 Lock 파일 시스템을 활용

Lock 파일을 기반으로 패키지가 설치될 수 있도록 한다면 위 (3) 단락에서 설명한 캐시 레이어의 장점을 얻을 수 있고, 예상치 못한 패키지 버전 업데이트도 방지할 수 있다.

 

(5) 멀티-스테이지 빌드를 활용

효과적으로 도커 이미지 사이즈를 줄이는 방법이다.

멀티-스테이지 빌드는 Dockerfile 1개에 FROM 구문을 여러 개 두는 방식이다.

특별한 이유가 없다면 멀티-스테이지 빌드를 사용하지 않을 이유는 없을 것 같다.

728x90
반응형

댓글