도커는 환경 격리, 확장성 향상, 운영 관리의 간소화를 가능하게 하며, 개발자에게는 개발, 테스트, 배포 과정을 크게 단순화해줍니다. 특히 새로운 프로젝트에 접근할 때, 문서가 부족하거나 오래되었더라도 Dockerfile만으로도 애플리케이션을 빠르게 로컬에서 실행할 수 있습니다.
DevOps의 핵심은 단순히 자동화된 파이프라인을 구축하는 것이 아니라, 애플리케이션을 일관되고 예측 가능한 방식으로 실행하는 것입니다. 이를 위해 Dockerfile을 작성하는 것은 시작점입니다.
기본적인 프론트엔드 배포 흐름
npm install– 의존성 설치npm run build– 정적 자원 빌드 및 번들링- 정적 파일 서빙 (예: nginx, http-server)
초기 버전의 Dockerfile
FROM node:alpine
ENV PROJECT_ENV production
ENV NODE_ENV production
WORKDIR /app
ADD . /app
RUN npm install && npm run build && npm install -g http-server
EXPOSE 80
CMD http-server ./public -p 80
이제 애플리케이션이 실행됩니다. 그러나 이 방법은 두 가지 문제를 가지고 있습니다:
- 빌드 시간이 길어짐
- 이미지 크기가 1GB 이상으로 커짐
devDependencies 분리 및 생산용 설치 최적화
개발 전용 패키지(예: ESLint, Jest, Mocha 등)는 빌드 시 필요하지 않습니다. --production 옵션을 사용하면 불필요한 패키지를 제외할 수 있습니다.
FROM node:alpine
ENV PROJECT_ENV production
ENV NODE_ENV production
WORKDIR /app
ADD package.json /app
RUN npm install --production
ADD . /app
RUN npm run build && npm install -g http-server
EXPOSE 80
CMD http-server ./public -p 80
캐시 활용을 통한 빌드 속도 향상
도커 빌드 시, ADD 명령어 이후의 명령은 입력 내용이 변경되지 않으면 캐시를 활용합니다. 따라서 package.json과 소스 코드를 분리하여 추가하면, 의존성 변경 없이 빌드 시 패키지 설치 단계를 캐시로 재사용할 수 있습니다.
FROM node:alpine
ENV PROJECT_ENV production
ENV NODE_ENV production
# 고정된 패키지 설치 (http-server)
RUN npm install -g http-server
WORKDIR /app
ADD package.json /app
RUN npm install --production
ADD . /app
RUN npm run build
EXPOSE 80
CMD http-server ./public -p 80
다단계 빌드로 이미지 크기 축소
빌드 과정에서 생성된 node_modules와 소스 코드는 최종 배포 시 필요하지 않습니다. 필요한 것은 build 폴더 내의 정적 파일뿐입니다. 이를 위해 다단계 빌드를 사용합니다.
FROM node:alpine as builder
ENV PROJECT_ENV production
ENV NODE_ENV production
WORKDIR /app
ADD package.json /app
RUN npm install --production
ADD . /app
RUN npm run build
# 최소 사이즈 기반 이미지 사용
FROM nginx:alpine
COPY --from=builder /app/public /usr/share/nginx/html
이제 이미지 크기는 약 50MB로 줄어듭니다.
CDN을 통한 정적 리소스 외부화
현재 이미지 크기의 대부분은 정적 파일(/public/static, /build) 때문입니다. 이 중 일부는 CDN에 업로드하고, 로컬 이미지에서는 필요 없는 파일을 제거할 수 있습니다.
예를 들어, 웹팩으로 빌드된 파일은 해시 값이 포함되어 있으며, 정적 경로를 통해 지속적으로 캐싱될 수 있습니다. 이를 위해 publicPath 설정을 조정하고, uploadCdn 스크립트를 통해 파일을 CDN에 업로드합니다.
FROM node:alpine as builder
ENV PROJECT_ENV production
ENV NODE_ENV production
WORKDIR /app
ADD package.json /app
RUN npm install --production
ADD . /app
RUN npm run build && npm run uploadCdn
FROM nginx:alpine
COPY --from=builder /app/public/index.html /app/public/favicon.ico /usr/share/nginx/html/
COPY --from=builder /app/public/static /usr/share/nginx/html/static
최종 이미지 크기는 20MB 미만으로 줄어들며, 배포 속도와 저장 공간 절약 효과를 얻을 수 있습니다.