e.g. Dockerfile (Next.js)
# 1) 빌드 스테이지
FROM node:20-alpine AS builder
# 작업 디렉터리 설정
WORKDIR /app
# 패키지 정의 및 잠금 파일 복사
COPY package.json package-lock.json ./
# 의존성 설치 (CI 모드로 정확히 재현)
RUN npm ci
# 소스 복사 및 빌드
COPY . .
RUN npm run build
# 2) 프로덕션 스테이지
FROM node:20-alpine AS runner
WORKDIR /app
# 빌드 결과물과 정적 파일만 복사
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/public ./public
COPY --from=builder /app/package.json ./package.json
COPY --from=builder /app/package-lock.json ./package-lock.json
# 프로덕션 전용 의존성만 설치
RUN npm ci --omit=dev
# Next.js가 3000 포트를 사용하므로 노출
EXPOSE 3000
# 컨테이너 구동 시 실행 명령
CMD ["npm", "start"]
FROM node:20-alpine AS builder
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
RUN npm run build
베이스 이미지 설정
node:20-alpine
이미지를 사용한다.
AS builder
를 붙여서 이 단계를 builder
라는 이름으로 참조한다.작업 디렉터리 지정
WORKDIR /app
으로 컨테이너 내부 작업 경로를 /app
으로 설정한다.
/app
을 기준으로 동작한다.패키지 파일 복사 및 의존성 설치
COPY package.json package-lock.json ./
RUN npm ci
애플리케이션 소스 복사 및 빌드
COPY . .
RUN npm run build
.next
디렉터리에 생성된다.FROM node:20-alpine AS runner
WORKDIR /app
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/public ./public
COPY --from=builder /app/package.json ./package.json
COPY --from=builder /app/package-lock.json ./package-lock.json
RUN npm ci --omit=dev
EXPOSE 3000
CMD ["npm", "start"]
베이스 이미지 재설정
동일하게 node:20-alpine
이미지를 사용하되, 이번에는 runner
단계로 명명한다.
빌드 결과물 복사
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/public ./public
COPY --from=builder /app/package.json ./package.json
COPY --from=builder /app/package-lock.json ./package-lock.json
-from=builder
를 통해 이전 스테이지에서 생성한 아티팩트를 가져온다..next
빌드 디렉터리, 정적 파일(public), 그리고 패키지 정보를 복사한다.프로덕션 의존성 설치
RUN npm ci --omit=dev
-omit=dev
옵션을 사용해 devDependencies
를 제외하고 설치한다.포트 노출 & 실행 명령
EXPOSE 3000
CMD ["npm", "start"]
npm start
를 실행해 애플리케이션을 시작한다.