애플리케이션을 도커 컨테이너로 만들어 사용할 때 신경쓰지 않으면 생성된 도커 이미지의 용량이 생각보다 커서 서버에 배포하거나 공유하기가 어렵게 됩니다.

하지만 약간만 신경을 쓴다면 훨씬 경량화된 이미지를 얻을 수 있는데요.

그 방법을 간단한 웹 어플리케이션을 만들어 보면서 알아보겠습니다.

도커 이미지 만들기

먼저 비교를 위해 무심하게(?) 도커 이미지를 만들어보겠습니다.

다만 도커이미지를 만들기 전에 리액트 프로젝트를 먼저 만들어 줍시다.

아래 명령어로 리액트 프로젝트를 생성해주세요!

npx create-react-app app --template typescript

위 명령어를 실행하면 아래 처럼 리액트 프로젝트가 만들어집니다.

Screen-Shot-2021-04-28-at-21.33.37

그러면 이제 도커 이미지를 만들기 위해 Dockerfile을 생성하고 코드를 작성하겠습니다.

FROM node:10

WORKDIR /app
COPY app /app
RUN npm install -g webserver.local
RUN npm install & npm run build

EXPOSE 3000
CMD webserver.local -d ./build

코드를 다 작성했으면 도커 이미지를 만들어 봅시다.

docker image build . --tag=demo-docker

위 명령어로 생성된 도커 이미지의 용량을 확인해보면 어마무시한 용량(1.19GB)으로 만들어진 것을 보실 수 있습니다. (ㅎㄷㄷ...)

Screen-Shot-2021-04-28-at-21.42.41

도커 이미지 경량화

어마무시한 용량을 어떻게 하면 줄일 수 있을지 단계별로 알아봅시다.

1단계. 가벼운 베이스 이미지를 사용하라

도커 이미지는 기본 베이스 이미지를 기반으로 만들게 되는데

이 베이스 이미지를 우리가 흔히 알고있는 서버 운영체제 ( centos, ubuntu )를 기반으로 만들게 되면 도커 환경에서는 불필요한 패키지나 파일들이 포함되어 있어 용량이 클 수 밖에 없습니다.
( 일반적으로 서버에 OS 깔면 용량이 꽤 되죠? 도커를 사용한 가상화도 결국 서버에 OS를 설치하는것과 같습니다. )

그래서 이러한 문제점을 해결하기 위해 도커를 위한 OS가 만들어졌고 그 중에 대표적인건 Alpine 입니다.

Alpine은 도커를 위한 리눅스 배포판입니다.
( 일반적인 OS를 도커에서 가볍게 사용하기 위해 커스터마이징한 버전인거죠. )

두말할 필요없이 Alpine 이미지로 베이스 이미지를 변경해서 다시 빌드해보겠습니다.

FROM node:10-alpine

WORKDIR /app
COPY app /app
RUN npm install -g webserver.local
RUN npm install & npm run build

EXPOSE 3000
CMD webserver.local -d ./build

짜잔! 1.19GB에서 366MB로 확 줄었습니다. 이전과 비교해서 엄청난 차이죠?

Screen-Shot-2021-04-28-at-21.53.00

하지만 우리는 여기서 만족할 수 없습니다. 더 줄여보죠.

2단계. Multi-stage build

Multi-stage build 란 빌드에만 필요한 작업을 나눠서 빌드하여, 추후 최종 컨테이너 이미지에는 포함시키지 않는 방법이다.

즉, 빌드 단계롤 분리함으로써 불필요한 요소들을 결과물에서 제거할 수 있게 만드는 방법입니다.

Dockerfile을 아래처럼 수정해봅시다.

FROM node:10-alpine AS build
WORKDIR /app
COPY app /app
RUN npm install && npm run build

FROM node:10-alpine
WORKDIR /app
RUN npm install -g webserver.local
COPY --from=build /app/build ./build
EXPOSE 3000
CMD webserver.local -d ./build

빌드의 단계가 2개로 나눠진것이 보이시죠?

빌드 환경 세팅 및 빌드를 한 후 실제 빌드된 파일로 웹 서비스를 세팅합니다.

빌드 결과는 아래와 같습니다. 90.8MB가 되었습니다. 두둥!

Screen-Shot-2021-04-28-at-22.17.40

자 여기서 여러분은 뭔가 부족하다는것을 느끼셔야합니다.
그건 바로, 웹서버를 왜 webserver.local 패키지를 이용하느냐는 거죠.

우리에게는 더 작고 빠른 nginx, apache가 있는데 말이죠 ^^;;

그러므로 이제 웹서버를 nginx로 변경해봅시다!

FROM node:10-alpine AS build
WORKDIR /app
COPY app /app
RUN npm install && npm run build


FROM nginx:stable-alpine
COPY --from=build /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

자 이제 최종 결과물을 봅시다. 어떤가요?

Screen-Shot-2021-04-28-at-22.24.36

무려 23.1MB가 되었습니다. 처음 시작할때 1.19GB였던거 기억하시죠? ㅎㅎ

지금까지 수정했던걸 살펴보면 아시겠지만 정말 사소한 차이가 큰 차이가 되는것을 보셨습니다.

감사합니다.