← 전체 글로 돌아가기

Docker

Docker 이미지 크기가 커지는 이유

같은 Dockerfile로 빌드해도 어느날부턴 용량이 확 늘어나는 경험. 그 원인을 파악하는 방법.

이미지 크기부터 측정한다

docker images | grep my-service

MB 단위로 쑥 커졌다면 그 전 빌드와 비교해야 한다. 큰 이미지는 배포 시간이 오래 걸리고, 레지스트리 스토리지도 늘어난다.

레이어별 크기를 본다

docker history my-service:latest --no-trunc

각 RUN, COPY 명령이 얼마나 큰 레이어를 만드는지 확인한다. 갑자기 커진 부분이 보일 것이다.

흔한 원인들

1. 빌드 캐시 누적

# npm install을 여러 번 실행하면 node_modules가 계속 쌓인다
docker builder prune

RUN 명령이 여러 번 npm install을 실행하거나, 빌드 중간 아티팩트를 정리하지 않으면 레이어가 커진다.

2. 베이스 이미지 변경

# Dockerfile 확인
grep "^FROM" Dockerfile

같은 애플리케이션을 node:alpine에서 node:latest로 바꾸면 800MB와 1.5GB의 차이가 난다.

3. 종속성 수 증가

grep -E "npm install|yarn add" Dockerfile

Package.json이 커지면서 devDependencies까지 전부 이미지에 포함되었을 수 있다.

최적화 기법

Multi-stage 빌드

# 빌드 단계
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production

# 실행 단계
FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/node_modules ./node_modules
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]

이렇게 하면 빌드에 필요한 도구들은 빌드 이미지에만 남고, 최종 이미지에는 필요한 것만 들어간다.

.dockerignore 활용

cat > .dockerignore << 'EOF'
node_modules
npm-debug.log
.git
.gitignore
.env
EOF

Docker build 시 불필요한 파일을 복사하지 않는다.

레이어 병합

# 나쁜 예: 각각 새로운 레이어 생성
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get install -y git

# 좋은 예: 한 번에
RUN apt-get update && \
    apt-get install -y curl git && \
    apt-get clean && rm -rf /var/lib/apt/lists/*

마지막의 apt-get clean은 패키지 캐시를 제거해서 레이어 크기를 줄인다.

현재 상태 파악

# 이미지 내부 파일 확인
docker run --rm my-service:latest du -sh / | sort -rh | head -10

# 또는 직접 들어가서 확인
docker run --rm -it my-service:latest /bin/sh
# 안에서 du -sh /* | sort -rh

예상과 다르게 큰 디렉터리가 있을 수 있다. 로그, 캐시, 또는 빌드 중간 파일일 수 있다.

배포 후 검증

최적화를 적용한 후 확인한다.

  1. 이미지 크기가 예상만큼 줄었는가
  2. 컨테이너가 정상적으로 실행되는가
  3. 성능에 변화가 없는가

특히 multi-stage 빌드를 적용했다면, 런타임 의존성이 모두 포함되었는지 확인해야 한다.