Docker
Docker 이미지 용량이 너무 크면 배포가 느려진다
같은 애플리케이션인데 배포 속도가 느릴 때 이미지 레이어를 최적화하는 방법.
Docker 이미지가 크면 배포 시간, 스토리지, 네트워크 대역폭이 모두 낭비된다. 로컬에서는 문제 없지만 배포할 때마다 몇 분이 걸리면, 이미지 용량부터 확인해야 한다.
현재 상태 파악
# 이미지 크기 확인
docker images | grep myapp
# 레이어별 용량 확인
docker history myapp:latest --no-trunc
각 레이어의 크기를 보면, 어느 단계에서 용량이 늘었는지 알 수 있다.
컨테이너 상태 확인
# 실행 중인 컨테이너의 디스크 사용량
docker exec myapp-container du -sh /app/
docker exec myapp-container du -sh /
불필요한 파일이 이미지에 포함되어 있지 않은가?
Dockerfile 최적화
1. Multi-stage build
빌드 단계와 실행 단계를 분리한다.
# ❌ 비효율: 모든 빌드 도구가 이미지에 남음
FROM node:18
WORKDIR /app
COPY . .
RUN npm install
RUN npm run build
CMD ["npm", "start"]
# ✅ 효율: 빌드 도구는 버리고 결과만 복사
FROM node:18 AS builder
WORKDIR /app
COPY . .
RUN npm install
RUN npm run build
FROM node:18-alpine # 작은 베이스 이미지
WORKDIR /app
COPY --from=builder /app/dist /app/dist
COPY --from=builder /app/node_modules /app/node_modules
COPY package.json .
CMD ["npm", "start"]
alpha -> alpine으로 바꾸면 베이스 이미지 자체도 훨씬 작다.
2. 불필요한 파일 제외
# .dockerignore 파일
node_modules/
npm-debug.log
.git/
.vscode/
TESTS/
*.md
.git 디렉토리만 제외해도 수십 MB가 줄어든다.
3. 캐시 활용
# ❌ 비효율: 코드 변경 시마다 의존성을 다시 설치
COPY . .
RUN npm install
# ✅ 효율: 의존성은 캐시하고, 코드 변경만 다시 빌드
COPY package.json package-lock.json ./
RUN npm ci # npm install 대신 npm ci 사용 (더 안정적)
COPY . .
RUN npm run build
package.json 변경까지만 캐시되고, 코드 변경은 빠르게 다시 빌드된다.
4. 베이스 이미지 선택
# 크기 비교 (MB)
# ubuntu:latest → ~77 MB
# node:18 → ~900 MB
# node:18-alpine → ~170 MB
# node:18-slim → ~160 MB
FROM node:18-alpine
alipne이나 slim을 쓰면 수백 MB 절약할 수 있다.
빌드 최적화
# 빌드 시 불필요한 것 제거
RUN npm install --production # dev 의존성 제외
RUN npm run build
RUN rm -rf /app/src /app/test /app/*.json # 소스 코드 제거
컴파일된 코드만 배포하면 된다면, 소스 코드는 제거해도 된다.
환경변수와 비교 기준
배포 환경과 로컬 빌드의 차이가 있을 수 있다.
# Docker Hub에서 이미지 크기 확인
docker pull myapp:latest
docker images | grep myapp
# 레지스트리의 메타데이터도 확인
skopeo inspect docker://myapp:latest
로컬 이미지보다 레지스트리의 이미지가 더 클 수 있다.
확인 결과와 그 의미
로컬 빌드: 500 MB
레지스트리: 500 MB → 일치하면 정상
로컬 빌드: 500 MB
레지스트리: 1 GB → 문제 있음
レジストリ에서 더 크면, 빌드 서버의 Dockerfile이 다를 가능성이 있다.
배포 후 확인
이미지 최적화 후에도 실행 시간을 확인한다.
# 컨테이너 시작 시간
time docker run myapp:latest
# 배포된 컨테이너 상태
docker logs <container-id> | head -10 # 시작 로그
이미지 크기와 시작 속도가 모두 개선됐는가?
최적화 체크리스트
- 현재 이미지 크기 확인
docker history로 레이어별 용량 파악- Multi-stage build 도입
.dockerignore파일 작성- 베이스 이미지를 alpine/slim으로 변경
npm ci사용, 캐시 활용- 불필요한 파일 제거 (소스, 테스트 등)
- 로컬과 배포 환경의 빌드 결과 비교
Docker 이미지 최적화는 한 번 하면 매번 배포할 때마다 시간이 절약된다. 작은 개선들이 모이면 큰 효과가 난다.