🤖

Next.jsをProdで動かす(Dockerのマルチステージビルド)

2023/09/02に公開

開発環境では動かせるようになったがProd環境においてどのように動かすべきなのか?確認する。

こちらを参考にさせていただきました
https://qiita.com/Nozomuts/items/b3a4fd57d0413d5d3437

Next.jsの公式Dockerファイルを見る

公式のDockerファイルを見るとマルチステージビルド済みのサンプルがあるので読んでいく。
https://github.com/vercel/next.js/blob/canary/examples/with-docker/Dockerfile

公式の node:18-alpine イメージを使いビルドを進めて、最終的には node server.js で稼働させる、という流れのようです。サンプルアプリで動かして見ます。

build iamge
$ git clone https://github.com/vercel/next.js.git
$ cd next.js
$ docker build -t msbuild-test .
〜中略〜
=> ERROR [runner 2/4] COPY --from=builder /app/public ./public
ERROR: failed to solve: failed to compute cache key: failed to calculate checksum of ref a5c7c046-64f0-4830-bd36-55713a118c09::3olumgdbc354ntwdr5wc06dca: "/app/public": not found

ビルド中に /app/public が見つからないというエラーが出ました。Next.jsの公式資料を読んでいくとPJ直下の /public は静的ファイルを配信できるディレクトリとのことだが、サンプルアプリでは public がなかったので作成して再度ビルドを試してみる。

build image
$ docker build -t msbuild-test .
$ docker run --publish 3000:3000 msbuild-test
Error: Cannot find module 'next/dist/server/lib/start-server'
〜中略〜
  code: 'MODULE_NOT_FOUND',
  requireStack: [ '/app/server.js' ]

ビルドは通ったが、今度はDocker起動時に /app/server.js が見つからないエラーが出ました。確かに手動で npm next build しても server.js はできない。ビルド時に複数のjsファイルをバンドルして1つのファイルを作ってくれる、と勝手に想像していました。

Next.jsのビルドやアウトプットの資料を読んでいると、自動的に出力するにはsharpというパッケージを導入する必要があるとのこと。

https://nextjs.org/docs/pages/api-reference/next-config-js/output#automatically-copying-traced-files

build image
$ npm i sharp
$ docker build -t msbuild-test .
$ docker run --publish 3000:3000 msbuild-test

インストールして再度動かして想定通り動きました。対応前と比較してイメージの容量が約半分ほどになっていました。

$ build image ls
msbuild-test             latest    cd06459f8eb6   10 minutes ago   240MB
next-auth-example-app    latest    49c1db887a1d   5 days ago       657MB

Prodで動かす際のイメージは得られました。またNodeを動かす上で押さえておくべきことや標準も少しずつ勉強していきたい。

Discussion