처음 도커를 쓸 때는 docker build가 돌아가는 게 신기했습니다.
그런데 어느 순간, 작은 수정 하나 하고 빌드할 때마다 5분씩 걸리기 시작했죠.
CI/CD 파이프라인에서 빌드가 병목이 되면서 배포도 느려졌습니다.
이 문제를 해결하면서 배운 게 “도커 이미지 최적화”였습니다.
이미지가 느려지는 이유

도커 이미지는 레이어(layer)의 집합입니다.
각 RUN, COPY, ADD 명령이 하나의 레이어를 만듭니다.
그래서 불필요한 레이어가 많아지면 이미지 크기가 커지고, 빌드도 느려집니다.
예를 들어 이런 Dockerfile을 보면 문제가 명확합니다.
FROM node:18
WORKDIR /app
COPY . .
RUN apt-get update
RUN apt-get install -y vim
RUN npm install
CMD ["npm", "start"]
여기서 RUN이 세 번이나 나와 있죠.
이렇게 하면 각 RUN마다 새로운 레이어가 생겨 이미지 크기가 불필요하게 커집니다.
RUN 명령은 하나로 합치자
위 코드를 아래처럼 바꾸면 훨씬 효율적입니다.
RUN apt-get update && \
apt-get install -y vim && \
npm install
이렇게 하면 한 번의 RUN으로 모든 패키지가 설치되고,
레이어도 하나로 줄어듭니다.
빌드 캐시도 더 잘 작동해서 재빌드 속도도 빨라집니다.
멀티 스테이지 빌드의 필요성

특히 Node.js, Python, Go 같은 언어로 만든 애플리케이션은
“빌드용 환경”과 “실행용 환경”이 다릅니다.
빌드 도구나 테스트 패키지까지 모두 들어가면 실행 이미지가 너무 커지죠.
그래서 나온 개념이 멀티 스테이지 빌드(Multi-stage build) 입니다.
# 빌드용 이미지
FROM node:18 AS builder
WORKDIR /app
COPY . .
RUN npm install && npm run build
# 실행용 이미지
FROM nginx:1.25
COPY --from=builder /app/dist /usr/share/nginx/html
이 방식의 핵심은 “필요한 결과물만 다음 단계로 복사한다”는 것입니다.
빌드 환경은 첫 번째 단계에서만 쓰이고,
실행 환경에는 빌드 결과물만 들어가기 때문에 이미지 크기가 획기적으로 줄어듭니다.
제가 실제로 적용했을 때,
이미지 용량이 1.3GB → 320MB로 줄었고, 빌드 시간도 절반 가까이 단축됐습니다.
캐시를 제대로 활용하는 순서
빌드 캐시는 도커의 가장 큰 장점 중 하나입니다.
하지만 명령 순서를 잘못 잡으면 캐시가 전혀 작동하지 않습니다.
예를 들어 COPY . .을 Dockerfile 맨 위에 써놓으면,
코드가 바뀔 때마다 모든 단계가 다시 실행됩니다.
정확한 순서는 이렇습니다.
FROM node:18
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
CMD ["npm", "start"]
이렇게 하면 의존성이 바뀌지 않았을 때는 npm install 단계가 캐시로 건너뛰어집니다.
매번 패키지를 다시 설치하지 않아도 되니까 빌드 속도가 훨씬 빨라지죠.
.dockerignore는 필수
도커 초보일수록 .dockerignore를 놓칩니다.
이 파일은 .gitignore와 비슷한 역할을 합니다 —
빌드할 때 도커가 불필요한 파일을 이미지에 포함하지 않게 막아주는 거죠.
node_modules
.git
Dockerfile
README.md
이 파일 하나만 잘 관리해도 이미지 용량이 수백 MB 줄어듭니다.
특히 node_modules나 venv 폴더가 이미지에 들어가면
도커가 매번 이 파일들을 복사하느라 빌드가 지연됩니다.
실제로 겪었던 문제
어느 날 빌드 서버에서 갑자기 디스크 용량 부족 오류가 떴습니다.
확인해보니, CI 서버가 캐시된 도커 이미지들을 계속 쌓아두고 있더군요.
docker system prune -a로 정리하고 나서,
빌드 캐시 전략을 완전히 새로 짰습니다.
불필요한 이미지 캐시는 주기적으로 삭제하고,
프로덕션용 이미지는 --squash 옵션을 써서 레이어를 합쳤습니다.
그 뒤로는 용량 문제도 사라지고,
빌드가 5분 걸리던 게 1분대로 줄었습니다.
지금 돌아보면

결국 도커 이미지 최적화는 “덜 쌓는 것”이 핵심입니다.
필요 없는 파일을 줄이고,
캐시가 효율적으로 작동하도록 Dockerfile 순서를 조정하는 것만으로도
도커 경험이 완전히 달라집니다.
한 번만 정리해두면, 팀 전체의 개발 효율이 눈에 띄게 올라갑니다.
특히 CI/CD 환경에서 도커 이미지를 자주 빌드한다면
이 부분은 필수로 알아야 합니다.
'docker' 카테고리의 다른 글
| Docker Compose로 여러 컨테이너 한 번에 다루기 (0) | 2025.11.12 |
|---|---|
| 도커 이미지와 컨테이너, 뭐가 다른 걸까 (0) | 2025.11.12 |
| Dockerfile 이해하기 — 이미지가 만들어지는 과정 (0) | 2025.11.12 |
| 도커로 무중단 배포(Blue-Green Deployment) 구현하기 (0) | 2025.11.12 |
| 도커와 CI/CD — 자동으로 빌드하고 배포하기 (0) | 2025.11.12 |