nx 활용시 docker 용량 최적화 하기

January 01, 2022

nx로 docker를 빌드시에는 nx 명령어를 활용해야 하는 영역도 필요하다보니, production 모드 활용시에 nx를 활용해야 하는 부분도 존재합니다. 물론, nx cloud 혹은 기타 cloud를 사용하여 빌드할 수도 있겠지만, 이러한 환경이 되지 않아 docker로 빌드해야 하는 경우 용량을 최적화 하는 방법에 대해 다뤄보고자 합니다.

npm prune을 활용하기

npm prune 명령어의 경우 npm install 이후 필요없는 패키지등을 node_modules에서 삭제하는 명령어입니다. nx를 활용하는 경우, 각 모노리포를 빌드하기 위해서 nx run-many 커맨드를 활용하는 경우에는, nx에 필요한 workspace 패키지들이 필요하여 어쩔수 없이 npm install을 production 모드로 빌드하더라도 dependency에 nx 패키지들을 설치해야 할 필요가 있습니다.

이러한 경우, docker의 multi-stage를 활용하면서, production에는 필요한 패키지만 만들 수 있도록 npm install 이후 npm prune을 사용하여 빌드할 수 있도록 변경해줍니다.

FROM node:14.18.0-alpine as builder

WORKDIR /opt/app
RUN npm install &&\
  npm prune --production

FROM node:14.18.0-alpine as runner
COPY --from=buoilder /opt/app/node_modules ./node_modules

npm prune --production 명령어 실행시 production mode로 dependencies를 제외한 나머지 파일들은 삭제하여 처리하게 됩니다. 이후 runner stage에서 builder에 대한 용량을 COPY하도록 설정해주면, production mode로 정제된 node_modules를 복사할 수 있게 됩니다.

nx에서 생성한 node_modules의 .cache 폴더 삭제하기

nx에서는 cloud를 사용하여 deploy 하는 경우에 cache를 적용하기 위해, node_modules install 후 nx 빌드 커맨드를 사용하게 되면, .cache/nx 내부에 nx 관련 캐시 폴더를 생성합니다. 이 캐시 용량이 무시하기 어렵습니다.

실제 프로젝트를 dockerfile로 빌드시에 docker image에 대한 용량이 캐시를 삭제하기 전에는 2GB가 넘었으나, 캐시 삭제 이후 1.5GB로 500MB정도를 절약할 수 있습니다.

FROM node:14.18.0-alpine as builder

WORKDIR /opt/app
RUN npm install &&\
  npm prune --production &&\
  rm -rf node_modules/.cache/nx/

FROM node:14.18.0-alpine as runner
COPY --from=buoilder /opt/app/node_modules ./node_modules

이렇게 첫번째에서 npm prune을 통해 depdencies에 선언된 패키지만 정제하였다면, 이후에는 nodemodules 폴더 내부의 .cache/nx 삭제를 통해 한번 더 nodemodules의 필요없는 캐시 폴더를 삭제합니다.

...