본문 바로가기
Q&A해결2026년 7월 17일1분 읽기

Docker로 만든 Node 이미지가 1.3GB나 되는데 이걸 어떻게 줄이나요?

d
docker_seungho
조회 929댓글 2

사이드 프로젝트 express 서버를 도커라이즈 했는데 빌드하고 나서 docker images 찍어보니 1.3GB가 나옵니다. 소스는 몇 MB밖에 안 되는데 이게 정상인가 싶어서요. 배포할 때마다 푸시가 너무 오래 걸려요 😅

Dockerfile은 이렇게 생겼습니다.

FROM node:20
WORKDIR /app
COPY . .
RUN npm install
CMD ["node", "server.js"]

node:20 이미지 자체가 큰 것 같기도 하고, node_modules도 통째로 들어가는 것 같은데 어디부터 손대야 할지 감이 안 옵니다.

댓글 2

김김영삼3개월 전
이미지가 큰 이유가 두 개 겹쳐 있어요. 하나는 베이스 이미지 node:20이 데비안 풀버전이라 그 자체로 1GB 가까이 되고, 다른 하나는 COPY . . 로 로컬 node_modules나 .git까지 다 들어가서예요.

일단 베이스를 node:20-slim이나 node:20-alpine으로 바꾸면 베이스만으로 수백 MB가 빠져요. alpine이 제일 작지만 bcrypt 같은 네이티브 모듈 빌드 이슈가 가끔 있으니 그런 거 쓰면 slim이 무난합니다.

그리고 프로젝트 루트에 .dockerignore 파일 만들어서 node_modules, .git, .env, npm-debug.log 넣어두세요. COPY . . 할 때 로컬 node_modules가 통째로 복사되면 캐시도 깨지고 크기도 커집니다.

마지막으로 빌드/런타임을 나누는 멀티스테이지로 가면 확실해요.

FROM node:20-slim AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .

FROM node:20-slim
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY --from=build /app .
CMD ["node", "server.js"]

package*.json 먼저 복사하고 npm ci 하는 순서가 중요한데, 소스만 바뀌었을 때 의존성 레이어를 캐시에서 재사용하려는 거예요. 트랜스파일 안 쓰고 그냥 실행만이면 단일 스테이지에 --omit=dev만 붙여도 꽤 줄어듭니다.
ddocker_seungho(guest)3개월 전
slim에 .dockerignore랑 --omit=dev 만 했는데도 300MB대로 뚝 떨어졌어요. 멀티스테이지는 나중에 빌드 스텝 붙일 때 적용해볼게요. 감사합니다!
Ctrl+Enter로 등록