はじめに
社内で開発中のWebシステムの大規模改修にあわせてNext.jsのバージョンアップを行いました。その際、SeverActionによるファイルのアップロードに1MBのサイズ制限がかかるようになり、その解決に少々時間を要しましたので対応内容を共有したいと思います。
発生した問題
Next.jsのバージョンを14から15にあげた時点から、ファイルのアップロード機能が1MBのサイズ制限にひっかかる現象が発生しました。以下エラー内容です。
uncaughtException: [Error: Body exceeded 1 MB limit.
To configure the body size limit for Server Actions, see: https://nextjs.org/docs/app/api-reference/next-config-js/serverActions#bodysizelimit] {
statusCode: 413
上記エラー内容に出力されているURLには、next.config.jsに以下の設定を追加すればサイズ制限を拡張できると記載されていました。
const nextConfig = {
experimental: {
serverActions: {
bodySizeLimit: "5mb",
},
},
}
module.exports = nextConfig;
ローカル環境で動作確認した際は問題なく動作したのですが、dockerコンテナとしてAWSのECSにデプロイすると設定が効いていないのか1MBの制限にかかってしまいました。
対応
結論、Next.jsのStandaloneモードでビルドすることで、問題が解消されました。
以下のページをみて、アプリが動作するためのファイルが.next/standaloneにすべて含まれるようになるということだったので、bodySizeLimitの設定そこに含まれるのではないかと考え、試してみたところうまく動作しました。
また副次的な効果として、Dockerイメージのサイズが1G強から100MB程度まで減りました。画面の動作も軽くなったような気がします。
Dockerfileは以下のように修正しています。
修正前のDockerfile
# 依存パッケージインストールのレイヤー
FROM public.ecr.aws/docker/library/node:22.14.0-alpine AS deps
WORKDIR /app
COPY package*.json ./
COPY prisma ./prisma/
RUN npm ci --omit=dev
# Build環境のレイヤー
FROM public.ecr.aws/docker/library/node:22.14.0-alpine as builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npx prisma generate
ENV GENERATE_SOURCEMAP false
RUN NODE_OPTIONS=--max-old-space-size=4096 npm run build
# 実行環境のレイヤー
FROM public.ecr.aws/docker/library/node:22.14.0-alpine as runner
WORKDIR /app
ENV NODE_ENV production
ENV DATABASE_URL xxxxx
COPY --from=builder /app/public ./public
COPY --from=builder /app/.next ./.next
COPY --from=deps /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json
EXPOSE 3000
CMD [ "node_modules/.bin/next", "start" ]
修正後のDockerfile
# Build環境のレイヤー
FROM public.ecr.aws/docker/library/node:22.14.0-alpine as builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npx prisma generate
ENV GENERATE_SOURCEMAP false
RUN NODE_OPTIONS=--max-old-space-size=4096 npm run build
# 実行環境のレイヤー
FROM public.ecr.aws/docker/library/node:22.14.0-alpine as runner
WORKDIR /app
ENV NODE_ENV production
ENV DATABASE_URL xxxxx
COPY --from=builder /app/public ./public
COPY --from=builder /app/next.config.js ./
COPY --from=builder /app/.next/static ./.next/static
COPY --from=builder /app/.next/standalone ./
EXPOSE 3000
CMD [ "node", "server.js" ]
そもそもなぜserverActions.bodySizeLimitの設定が効かなかったのか、など理解が追いついていないところがありますが、取り急ぎ記事にします。