書くこと
セキュリティ要件のため通信を HTTPS で受ける Custom Server を開発する、ネットワーク要件のため Next.js を Docker コンテナで動かすことがあり、本番環境デプロイするにあたり調べて動かしたことを書きます。
Next.js バージョン 14 を前提とします。
結論:Dockerfile
FROM node:20 AS builder
WORKDIR /app
COPY ./frontend /app
RUN npm ci
RUN npm run build
RUN npm run build:https-server
FROM node:20 AS runner
WORKDIR /app
COPY --from=builder /app/package*.json /app
COPY --from=builder /app/node_modules /app/node_modules
COPY --from=builder /app/.next /app/.next
COPY --from=builder /app/https-server/dist /app/https-server/dist
ENV NODE_ENV=production
EXPOSE 443
CMD ["node", "/app/https-server/dist/server.js"]
NPM Scripts は次を前提とします。
- "build": "next build"
- "build:https-server": "tsc --project tsconfig-for-https-server.json"
ディレクトリは次を前提とします。
- frontend
- package.json
- tsconfig.json
- tsconfig-for-https-server.json
- src
- https-server
- src
- server.ts(Custom Server 実装)
- dest
- server.js(Custom Server ビルド成果物)
- src
解説
Next.js ではビルド成果物を最小限にするため、ビルドの選択肢として standalone output mode がありますが、Custom Server では使えません。
When using standalone output mode, it does not trace custom server files. This mode outputs a separate minimal server.js file, instead. These cannot be used together.
Configuring: Custom Server | Next.js
next.config.js Options: output | Next.js を参考に、次を COPY して動かすことができました。
- package*.json
- node_modules
- .next
静的コンテンツは次のように Docker コンテナ、または CDN などにデプロイできます。
COPY --from=builder /app/.next/static /app/.next/static
COPY --from=builder /app/public /app/public
余地として依存関係のトレースなどでより最小限のビルド成果物にすることもできそうです。
公式に対応する動きもあるようなので、そのうちより簡単により最小限のビルド成果物で動かせるようになるかもしれない。
Support custom servers with minimal node modules by MJez29 · Pull Request #72966 · vercel/next.js