Docker는 DevOps 파이프라인에서 핵심 기술로 자리 잡았지만, 이미지 용량이 크거나 빌드 시간이 과도하게 길어지는 문제는 여전히 많은 개발자들이 느끼는 문제점 중 하나입니다. 코드 한 줄 고치고 배포하는 5분씩 걸리는 것 자체가 너무 불편하게 느껴지죠. 특히 실서비스 배포 시에는 빌드 효율과 배포 속도가 곧 사용자 경험과 직결되기 때문에, 최적화는 선택이 아닌 필수가 되었습니다. 오늘 이 글에서는 실제 사례를 바탕으로 Docker 이미지 최적화 핵심 전략인 멀티스테이지 빌드, .dockerignore 활용, 레이어 캐시 전략으로 용량도 절반이하로 줄어들고 빌드 시간도 확 줄어드는 것을 경험해보시면 좋을 것 같습니다.
멀티스테이지 빌드로 이미지 크기 50% 줄이기
멀티스테이지 빌드는 Docker 이미지 최적화에서 가장 효과적인 기법 중 하나입니다. 기존에는 애플리케이션 빌드와 실행 환경을 하나의 이미지에 모두 포함시켜야 했지만, 멀티스테이지를 활용하면 빌드 환경과 런타임 환경을 분리하여 실행에 불필요한 파일과 라이브러리를 배제할 수 있습니다.
# 1단계: 빌드용 이미지
FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# 2단계: 실행용 이미지 (경량)
FROM node:18-slim
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
CMD ["node", "dist/main.js"]
📊 실제 용량 비교 (React 프로젝트 기준):
- 일반 방식: 약 500MB
- 멀티스테이지 적용: 약 150MB
→ 약 70% 이상 용량 절감 효과
또한, CI/CD 환경에서 멀티스테이지 빌드를 적용하면 전송 속도 향상, 배포 시간 단축, 보안 노출 최소화 등의 효과도 함께 얻을 수 있습니다.
.dockerignore 제대로 활용하기
.dockerignore는 Docker 빌드 시 컨텍스트(Context) 디렉토리에서 제외할 파일 목록을 정의하는 설정 파일입니다. 많은 개발자들이 무심코 넘기지만, 잘 작성된 .dockerignore는 빌드 속도를 획기적으로 개선하고 이미지 용량 증가를 방지하는 핵심 요소입니다.
.git
node_modules
npm-debug.log
Dockerfile
.dockerignore
README.md
tests/
컨텍스트 디렉토리에 포함된 파일들은 Docker 엔진이 전부 처리 대상으로 간주하기 때문에, 용량이 클수록 도커 데몬과의 통신 시간, 압축 시간, 초기 빌드 시간 모두 증가합니다.
📊 실제 테스트 결과:
- .dockerignore 미작성: 빌드 시작까지 평균 6~10초 지연
- .dockerignore 적용: 1~2초 이내 바로 빌드 진행
정리하면, .dockerignore는 단순한 설정 파일이 아닌, 빌드 성능 향상과 이미지 최적화의 핵심 도구입니다.
레이어 캐싱 전략으로 빌드 시간 단축
Docker는 이미지 빌드시 이전 레이어를 캐싱해두고, 동일한 명령이 실행될 경우 캐시를 재활용합니다. 이를 레이어 캐싱이라고 하며, 이를 제대로 활용하면 빌드 시간을 절반 이하로 줄일 수 있습니다.
# 비효율적 예시
COPY . .
RUN npm install
# 개선된 예시
COPY package*.json ./
RUN npm install
COPY . .
위 예제에서 개선된 방식은 종속성 설치 명령어가 변경되지 않는 한 캐시가 재사용되며, 매번 전체 빌드를 다시 하지 않아도 됩니다.
📊 빌드 시간 비교 (Express 프로젝트 기준):
- 캐싱 없이 매번 전체 빌드: 평균 40초
- 캐싱 적용 후: 8~15초
추가 전략:
- docker build --cache-from 옵션 활용
- DOCKER_BUILDKIT=1 설정
- CI/CD에서 외부 캐시 저장소 연동
Docker 최적화는 DevOps 효율의 핵심
빌드 시간이 길거나 이미지 용량이 비정상적으로 크다면, 이는 단지 기술적 불편을 넘어 운영 효율성과 배포 신뢰성에 직접적인 악영향을 줍니다.
멀티스테이지 빌드를 통해 불필요한 요소를 제거하고, .dockerignore로 컨텍스트를 정리하며, 레이어 캐싱 전략으로 빌드 속도를 개선하는 세 가지 핵심 전략만으로도 큰 변화를 만들 수 있습니다.
사실 실무에서도 Docker 최적화를 꼭 해야하나 하는 의문이 들 때가 있었습니다. 하지만 막상 멀티스테이지를 적용하고나니 500MB가 넘던 이미지가 150MB로 줄어들고 빌드 시간도 반 이상 단축되는 것들이 결국 개발 속도 자체를 빠르게 해주는 것을 경험할 수 있었습니다. 처음부터 너무 완벽하게 할 필요는 없지만, .dockerignore부터 제대로 작성 후 멀티스테이지 적용해보시는 것을 추천합니다. 레이어 캐싱은 그 이후에 신경써도 충분할 것 입니다.