# ============================================ # Stage 1: Dependencies # ============================================ FROM node:20-alpine AS deps WORKDIR /app # Package files만 먼저 복사 (캐싱 최적화) COPY package.json package-lock.json ./ # 의존성 설치 RUN npm ci --only=production # ============================================ # Stage 2: Builder # ============================================ FROM node:20-alpine AS builder WORKDIR /app # 의존성 복사 COPY package.json package-lock.json ./ RUN npm ci # 소스 코드 복사 COPY . . # 빌드 시점에 환경 변수 주입 (NEXT_PUBLIC_* 변수만) ARG NEXT_PUBLIC_BASE_PATH ARG NEXT_PUBLIC_KAKAO_APP_KEY ARG NEXT_PUBLIC_SUPABASE_URL ARG NEXT_PUBLIC_SUPABASE_ANON_KEY ARG NEXT_PUBLIC_PORTONE_IMP_CODE ENV NEXT_PUBLIC_BASE_PATH=$NEXT_PUBLIC_BASE_PATH ENV NEXT_PUBLIC_KAKAO_APP_KEY=$NEXT_PUBLIC_KAKAO_APP_KEY ENV NEXT_PUBLIC_SUPABASE_URL=$NEXT_PUBLIC_SUPABASE_URL ENV NEXT_PUBLIC_SUPABASE_ANON_KEY=$NEXT_PUBLIC_SUPABASE_ANON_KEY ENV NEXT_PUBLIC_PORTONE_IMP_CODE=$NEXT_PUBLIC_PORTONE_IMP_CODE # Next.js 빌드 (standalone 모드) RUN npm run build # ============================================ # Stage 3: Runner # ============================================ FROM node:20-alpine AS runner WORKDIR /app # 보안을 위해 non-root 유저 생성 RUN addgroup --system --gid 1001 nodejs RUN adduser --system --uid 1001 nextjs # 필요한 파일만 복사 COPY --from=builder /app/public ./public COPY --from=builder /app/.next/standalone ./ COPY --from=builder /app/.next/static ./.next/static # 권한 설정 RUN chown -R nextjs:nodejs /app USER nextjs # 포트 설정 EXPOSE 3000 # 환경 변수 ENV NODE_ENV=production ENV PORT=3000 ENV HOSTNAME="0.0.0.0" # 헬스체크 HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ CMD node -e "require('http').get('http://localhost:3000/api/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})" # 실행 CMD ["node", "server.js"]