Turborepo에서는 Docker 이미지를 빌드하기 위한 가이드를 제공하고 있는데요, 가이드를 잘 보면 npm
과 Next.js
의 예시만 제공하고 있어서 리액트 및 다른 패키지 매니저 기반의 프로젝트에서는 적용하기 어려울 수 있습니다.
필자의 프로젝트 환경은 Turbo와 pnpm 기반의 모노레포 개발 환경이며, React 앱을 Nginx를 이용해 제공하는 도커 컨테이너를 만들기 위해 아래와 같은 과정을 거쳤습니다.
예시 파일은 turbo의 Docker example을 기반으로 작성되었으며 필자의 환경과 일치하지는 않습니다. turbo의 예시와 다른 부분만 상세히 설명하겠습니다. 나머지 부분은 turbo의 가이드를 참고해주세요.
FROM node:18-alpine AS base
FROM base AS builder
RUN apk add --no-cache libc6-compat
RUN apk update
WORKDIR /app
# pnpm으로 turbo를 global 설치하는게 생각대로 되지 않아 npm을 이용해 global 설치했습니다.
RUN npm install -g turbo@{version}
COPY . .
RUN turbo prune app-name --docker
FROM base AS installer
ARG NODE_ENV
RUN apk add --no-cache libc6-compat
RUN apk update
WORKDIR /app
COPY --from=builder /app/out/json/ .
# pnpm-lock file을 같이 copy해줍니다.
COPY --from=builder /app/out/pnpm-lock.yaml ./pnpm-lock.yaml
# pnpm install시 세부적인 설정은 환경에 따라 다를 수 있습니다. 필자는 corepack을 사용했습니다.
RUN corepack enable && corepack prepare pnpm@{version} --activate
RUN pnpm install --frozen-lockfile --prod=false
COPY --from=builder /app/out/full/ .
# pnpx을 이용해 빌드가 필요한 app을 필터링해 turbo build를 실행합니다.
RUN pnpx turbo run build --filter={app-name}
FROM nginx:alpine
COPY ./apps/{app-name}/nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=installer /app/apps/{app-name}/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
FROM node:18-alpine AS base
# 빌드 단계
FROM base AS builder
RUN apk add --no-cache libc6-compat
RUN apk update
WORKDIR /app
RUN npm install -g turbo@{version}
COPY . .
RUN turbo prune app-name --docker
# 설치 단계
FROM base AS installer
ARG NODE_ENV
RUN apk add --no-cache libc6-compat
RUN apk update
WORKDIR /app
COPY --from=builder /app/out/json/ .
COPY --from=builder /app/out/pnpm-lock.yaml ./pnpm-lock.yaml
RUN corepack enable && corepack prepare pnpm@{version} --activate
RUN pnpm install --frozen-lockfile --prod=false
COPY --from=builder /app/out/full/ .
RUN pnpx turbo run build --filter={app-name}
# Nginx 설정 단계
FROM nginx:alpine
COPY ./apps/{app-name}/nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=installer /app/apps/{app-name}/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
참고자료
https://turbo.build/repo/docs/guides/tools/docker
https://github.com/vercel/turborepo/issues/5462