case 1) 명령어 실행을 통해 파일 제거
RUN ["/bin/sh", "-c", "find . ! -name dist ! -name node_modules -maxdepth 1 -mindepth 1 -exec rm -rf {} \\\\;"]
case 2) 빌드 과정 후 필요한 파일만 복사하여 컨테이너 실행
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
도커는 이미지를 만들 때 각 명령어마다 Layer를 만들어두고 이전과 변한 것이 없을 경우 재사용 한다.
각 파일마다 가지고 있는 역할을 세분화하여 각 레이어를 생성함으로써 소스 코드 수정 시 재 빌드 시간 단축시킬 수 있다.
이를 나누지 않을 경우 코드를 단 한 줄도 바꾸지 않아도 매번 패키지를 설치하고 빌드를 실행하기 때문에, CPU, 메모리 자원을 낭비할 수 있다.
ex) 다음과 같은 과정으로 Layer를 관리해 줄 수 있다.
# Depndencies 설치 환경 (deps)
FROM node:16-alpine AS deps
~~~
#Build(dist) 파일 생성 (builder), 그 외 서버 실행(runner)에 필요없는 파일은 모두 제거
FROM node:16-alpine AS builder
~~~
# 서버 실행 (runner)
FROM node:16.16.0 AS runner
~~~
-> npm run start
프로세스: 3개
-> node dist/src/main
프로세스: 1개
( 해당 내용 원리는 https://spartacodingclub.kr/blog/optimizing-dockerfile 참고)
Dockerfile
# Dpendencies 설치 환경 (deps)
FROM node:16-alpine AS deps
WORKDIR /app
COPY ["package.json", "yarn.lock", "./"]
RUN ["yarn", "install"]
# Build(dist) 파일 생성 (builder)
FROM node:16-alpine AS builder
WORKDIR /app
COPY ["tsconfig.build.json", "tsconfig.json", "./"]
COPY ["src/", "./src/"]
COPY --from=deps /app/node_modules ./node_modules
RUN ["npx", "nest", "build"]
# 서버 실행 (runner) - node_modules, dist 파일만 복사
FROM node:16.16.0 AS runner
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
CMD ["node", "dist/main"]
EXPOSE 8000
🔎 해당 Dockerfile을 통해 동일한 프로젝트 테스트 결과, 서버 실행 (runner) 과정에서node:16-alpine
버전을 사용했을 때 용량이 엄청 줄어드는 걸 확인할 수 있었다.
alpine 버전
- 적용 전: 1.48GB -> 적용 후: 344.23M
node:16.16.0 버전
- 적용 전: 1.48GB -> 적용 후: 1.08GB