멀티 스테이지 컨테이너 빌드로 배포 간소화하기
애플리케이션을 빌드 환경과 함께 완전하게 배포하면 시스템 크기가 매우 커집니다. 빌드 및 테스트 환경까지 포함되기 때문입니다. 배포할 파일만 추출하는 것이 문제가 아니더라도 시간이 많이 소요됩니다.
컨테이너를 사용하면 이 과정을 자동화할 수 있습니다.
멀티 스테이지 빌드의 개념
하나의 Dockerfile에 여러 컨테이너 단계를 정의하고, 이전 단계에서 생성된 아티팩트만 다음 단계로 복사하는 방식입니다. Node.js로 빌드한 JavaScript 웹사이트가 대표적인 예입니다.
크기 비교
- Node.js 빌드 환경: 약 400~600 MB
- nginx 웹서버: 약 20 MB
- 웹사이트 파일: 약 2 MB
전체를 하나의 컨테이너로 만들면 600 MB 이상이지만, 실제 운영에 필요한 것은 22 MB(nginx + 웹사이트)뿐입니다. 불필요한 소프트웨어가 포함되어 보안 위험도 커집니다. 멀티 스테이지 빌드로 이 문제를 해결할 수 있습니다.
멀티 스테이지 Dockerfile 예제
1단계에서는 Node.js 컨테이너를 빌드 시스템으로 사용해 웹사이트를 빌드합니다. 2단계에서는 경량 nginx 컨테이너(Alpine 기반)에 빌드 결과물만 복사합니다.
# Stage 1: 빌드 시스템
FROM node:8.11.3 as buildsystem
# 소스 코드 복사
COPY ./source /root/frontend
# 프론트엔드 빌드
WORKDIR /root/frontend/
RUN npm install \
&& npm run build
#####################################################################
# Stage 2: 운영 환경
FROM nginx:alpine
# 1단계에서 빌드된 결과물 복사
RUN mkdir -p /var/www/html/<MyApp>
COPY --from=buildsystem /root/frontend/dist/ /var/www/html/<MyApp>/
# nginx 기본 설정 추가
ADD default.conf /etc/nginx/conf.d/
# 포트 노출
EXPOSE 80
# nginx 시작
CMD ["nginx", "-g", "daemon off;"]
결과는 필수 요소만 포함한 경량 컨테이너입니다. Alpine Linux 기반 nginx를 사용해 크기를 최소화했습니다.
추가 이점
- 검증된 커뮤니티 이미지를 베이스 이미지로 사용하므로 직접 만들고 유지보수할 필요가 없습니다.
- 시스템 업데이트 시 커뮤니티 이미지만 정기적으로 교체하면 됩니다.
- GitLab CI/CD 파이프라인 등에서 훌륭하게 자동화할 수 있습니다.