멀티 스테이지 빌드와 Turborepo의 turbo prune 명령어를 활용하여 이미지 크기를 대폭 줄이는 방법에 대해 알아보겠습니다.
dockerfileCopyFROM node:20-slim AS base
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
RUN corepack enable
RUN apt-get update && apt-get install -y
dockerfileCopyFROM base AS builder
WORKDIR /app
ARG APP_NAME
ENV APP_NAME=${APP_NAME}
COPY . .
RUN npx turbo prune --scope=${APP_NAME} --dockere --scope=${APP_NAME} --docker
베이스 이미지를 기반으로 builder 스테이지를 생성합니다.
APP_NAME을 인수로 받아 환경 변수로 설정합니다.
turbo prune 명령어를 사용하여 의존성을 최적화합니다.
--docker 옵션을 통해 도커용으로 최적화된 출력을 생성합니다.
out과 full 디렉토리로 구분하여 의존성을 정리합니다.
turbo prune을 사용하면 워크스페이스의 파일이 추가될 때마다 처음부터 다시 설치하는 문제를 해결할 수 있습니다. 의존성과 관련된 부분만 캐싱하여 빌드 속도를 개선합니다.
dockerfileCopyFROM base AS installer
WORKDIR /app
ARG APP_NAME
ENV APP_NAME=${APP_NAME}
COPY .gitignore .gitignore
COPY --from=builder /app/out/json/ .
COPY --from=builder /app/out/pnpm-lock.yaml ./pnpm-lock.yaml
COPY --from=builder /app/out/pnpm-workspace.yaml ./pnpm-workspace.yaml
RUN pnpm install --frozen-lockfile
dockerfileCopyCOPY --from=builder /app/out/full/ .
RUN pnpm --filter ${APP_NAME} build
dockerfileCopyFROM base AS runner
WORKDIR /app
ARG APP_NAME
ENV APP_NAME=${APP_NAME}
ENV NODE_ENV=production
COPY --from=installer /app/apps/${APP_NAME}/.next/standalone ./
COPY --from=installer /app/apps/${APP_NAME}/.next/static ./apps/${APP_NAME}/.next/static
COPY --from=installer /app/apps/${APP_NAME}/public ./apps/${APP_NAME}/public
installer 스테이지에서 필요한 파일들을 복사합니다.
Next.js의 standalone 옵션을 사용하여 경량화된 프로덕션 빌드를 생성합니다.
next.config.mjs 파일에서 output: 'standalone' 옵션을 설정해야 합니다.
node_modules를 설치하지 않고도 독립적으로 배포할 수 있습니다.
start.sh 스크립트 생성
dockerfileCopyRUN echo "#!/bin/sh\n\
if [ -z \"\$APP_NAME\" ]; then\n\
echo \"APP_NAME 환경 변수가 설정되지 않았습니다.\"\n\
exit 1\n\
fi\n\
echo \"Starting application \${APP_NAME}...\"\n\
exec node apps/\${APP_NAME}/server.js" > start.sh
RUN chmod +x start.sh
ENV PORT=8000
EXPOSE 8000
ENTRYPOINT ["./start.sh"]
https://nextjs.org/docs/app/building-your-application/deploying
https://turbo.build/repo/docs/guides/tools/docker
https://nextjs.org/docs/pages/api-reference/next-config-js/output
https://turbo.build/repo/docs/reference/prune
https://turbo.build/repo/docs/reference/prune
https://www.inflearn.com/blogs/3871
https://oliveyoung.tech/blog/2024-06-16/next-cdn-standalone/