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
예상과 다르게 큰 디렉터리가 있을 수 있다. 로그, 캐시, 또는 빌드 중간 파일일 수 있다.
배포 후 검증
최적화를 적용한 후 확인한다.
- 이미지 크기가 예상만큼 줄었는가
- 컨테이너가 정상적으로 실행되는가
- 성능에 변화가 없는가
특히 multi-stage 빌드를 적용했다면, 런타임 의존성이 모두 포함되었는지 확인해야 한다.