도커 이미지의 용량이 작아지면 docker push, docker pull 하는 속도가 빨라진다. 이미지를 통해서 컨테이너를 띄우는 속도도 빨라진다. 더 많은 도커 이미지를 호스트에 저장할 수도 있다.
꼭 필요한 패키지 및 파일만 추가
컨테이너는 하나의 프로세스를 실행하는 데만 초점이 맞춰져 있기 때문에 해당 프로세스를 실행하는데 필요없는 패키지나 파일은 모두 제거하는 것이 좋다.
컨테이너 레이어 수 줄이기
컨테이너 레이어 수는 Dockerfile의 RUN 개수와 같기 떄문에 RUN 명령어는 최소한으로 사용하는 것이 좋다.
FROM alpine:3.14
LABEL maintainer="FastCampus Park <fastcampus@fastcampus.com>"
LABEL description="Simple utility to send slack message easily."
# Install needed packages
RUN \
apk add --no-cache bash curl git && \
git clone https://github.com/course-hero/slacktee /slacktee && \
apk del --no-cache git
RUN chmod 755 /slacktee/slacktee.sh
# Run
WORKDIR /slacktee
ENTRYPOINT ["/bin/bash", "-c", "./slacktee.sh"]
&& 를 사용해서 세 가지 명령어를 한 개의 RUN 명령어로 만들었다. 도커 이미지 상에서는 캐시를 필요로 하지 않기 때문에 –no-cache 옵션을 사용하는 것이 좋다. 불필요한 캐시를 지우는 명령어를 넣는 것도 좋은 방법이다.
경량 베이스 이미지 선택
가장 많이 사용하는 방법으로 debian의 slim 계열, alpine, stretch (파일시스템만 존재하는 이미지) 과 같은 용량이 아주 작은 이미지를 베이스 이미지로 사용한다.
FROM node:16-alpine
LABEL maintainer="FastCampus Park <fastcampus@fastcampus.com>"
LABEL description="Simple server with Node.js"
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 8080
CMD [ "node", "server.js" ]
위는 node:16-alpine를 베이스 이미지로 사용했다. node 이미지는 아래서 볼 수 있는것과 같이 910MB 엄청 크지만 node:16-alpine는 115MB이다. alpine 이미지는 alpine linux를 기반으로 한 이미지로, alpine linux는 도커 컨테이너를 위해 만들어진 이미지 배포판이다 보니 경량화 되어 있다.
멀티 스테이지 빌드 사용
멀티 스테이지 빌드 기능을 사용하면 빌드 스테이지와 릴리즈 스테이지를 나누게 되고, 빌드 때 필요한 빌드 의존성을 빌드 스테이지에서만 사용하고 릴리즈 스테이지에서는 빌드 결과물만 복사해서 릴리즈 이미지의 용량을 줄일 수 있다.
FROM node:16-alpine AS base
LABEL maintainer="FastCampus Park <fastcampus@fastcampus.com>"
LABEL description="Simple server with Node.js"
WORKDIR /app
COPY package*.json ./
FROM base AS build
RUN npm install
FROM base AS release
COPY --from=build /app/node_modules ./node_modules
# Bundle app source
COPY . .
EXPOSE 8080
CMD [ "node", "server.js" ]
multistage pipeline은 도커 파일의 문법 중 하나이다. multistage pipeline가 나오면서 FROM node:16-alpine AS base
과 같이 AS 문법이 추가되었다. AS를 사용하면서 다음 FROM 이 나오기 전까지를 하나의 블록으로 잡고 base라는 임시 이미지 이름을 부여한다. 이렇게 하면 FROM 블록을 여러번 사용할 수 있게 된다.
위에서는 base 블록, build 블록, release 블록이 있다. build 블록과 release 블록은 base를 기반으로 하는 것을 볼 수 있다. 이 말은 base로 정의된 레이어를 재사용한다는 것이다. COPY에 –from=build 옵션을 통해서 빌드 스테이지에서 파일을 복사해온다. 원래 COPY는 호스트 운영체제에서 컨테이너 안으로 복사하는 명령어 였는데 –from= 옵션을 추가하면 특정 스테이지에서 파일을 복사해올 수 있다. –from=build 는 build 스테이지에서 빌드된 nodejs 패키지들을 릴리스 스테이지에 복사해오는 것이다.
빌드 때 사용하는 의존성이 많아질수록 multistage pipeline을 사용했을 때의 효과가 크다.