next.config.jsnextConfigに、output: standaloneを指定すると軽くなるらしいので試してみたが、Dockerfileの書き方に苦戦したのでメモ

Dockerfile

取り敢えず動く単純なDockerfileはこれ。 ユーザー名の指定や、base, builderのステージを追加をしたい場合はVercelがGitHubに載せているDockerfileが参考になる。

FROM node:20.10-bullseye as builder

WORKDIR /work
COPY package.json /work/
COPY package-lock.json /work/

RUN npm i

COPY . .
RUN npm run build

FROM node:20.10-bullseye

COPY --from=builder /work/.next/standalone/ /work/
COPY --from=builder /work/public/ /work/public/
COPY --from=builder /work/.next/static/ /work/.next/static/

EXPOSE 3000

WORKDIR /work/

CMD ["node", "server.js"]

原因と対策

本来publicディレクトリとstaticディレクトリは、Next.jsのserver.jsからではなく、CDNから配信することが望ましいため、デフォルトでビルドのときにコピーされない。

https://nextjs.org/docs/pages/api-reference/next-config-js/output#:~:text=This%20minimal%20server,a%20CDN%20instead

なので、もしNext.jsサーバーからstaticなファイルを配信したい場合は、手動でコピーする必要があった。