🦖

[Turborepo] モノレポ環境内のNext.jsアプリをビルドする

2024/03/13に公開

モノレポ化されているリポジトリの中のNext.jsアプリをデプロイするのに必要だったDockerイメージを作成するときに、色々模索したのでその備忘録です。詳しい解説は端折ってますが、誰かの参考になれば幸いです。

フォルダ構成

.
├── apps
│   └── web(Next.js)
│        ├── docker
│        │    ├── development
│        │    │   └── Dockerfile
│        │    └── prod
│        │         └── Dockerfile
│        └ package.json
├── packages
│   └── db
│        └ package.json
├── shared
│   └── package.json
├── package.json
└── yarn.lock

今回はTurborepoで管理しているモノレポ環境内のNextアプリのDockerイメージを作成します。

Nextの設定

スタンドアローンモードを有効にすることで、イメージサイズを削減できるので設定します。
アプリはnext startではなく、node server.jsを実行することで起動できます。
publicフォルダや.next/staticフォルダはコピーされないため、Dockerfileの記述時に別途コピーするように注意が必要です。

next.config.js
const nextConfig = {
  // ...他の設定
  output: "standalone",
}

module.exports = nextConfig

Dockerfileの記述

Dockerfile
FROM node:18-alpine AS base
WORKDIR /app
RUN corepack enable yarn

FROM base AS turbo
RUN yarn global add turbo
COPY . .

COPY ./apps/web/.env.development ./apps/web/.env.production
RUN turbo prune --scope=@workspaceName/web --docker

FROM base AS builder
# Nextをビルドするにはnode-gypモジュールが必要で、これらのビルドにはpythonが必要だがalpineにはない。
RUN apk add --no-cache python3 make g++ libc6-compat
COPY --from=turbo /app/out/json/ .
COPY --from=turbo /app/out/yarn.lock ./yarn.lock
RUN yarn install

COPY --from=turbo /app/out/full/ .
RUN yarn turbo run build --filter=@workspaceName/web
RUN apk --no-cache add curl && curl -sf https://gobinaries.com/tj/node-prune | sh && node-prune


FROM base AS runner
#root権限で実行しない
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
USER nextjs

COPY --from=builder --chown=nextjs:nodejs app/apps/web/.next/standalone ./
# スタンドアローンモードでpublicと.next/staticはコピーされないため、ここでコピーする
COPY --from=builder --chown=nextjs:nodejs app/apps/web/public ./apps/web/public
COPY --from=builder --chown=nextjs:nodejs app/apps/web/.next/static ./apps/web/.next/static

WORKDIR /app/apps/web

CMD node server.js

参考文献

GitHubで編集を提案

Discussion