画像をMiniOサーバにアップロードするアプリを作成してビルド後自鯖にデプロイしてみたところ、Server Actionsの1MB制限に引っかかってしまいアップロードできない事態に見舞われました。開発環境だと問題なく上げられたのでちょっと困りました。
Next.js13以下ではnext.config.tsに下記を追加することで回避できたようですが、Next.js15 App Routerでは使用できません。
// Next.js13以前の設定
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
// これを追記
experimental: {
serverActions: {
bodySizeLimit: '500mb',
},
},
};
export default nextConfig;
Next.js15ではスタンドアロンモード(最小限の構成でビルド)でデプロイすることでExpressのserver.js側でアップロード上限を設定できるようなのでやってみました。next.config.tsに下記を追記します。
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
// スタンドアロンモードで出力
output: "standalone",
};
export default nextConfig;
設定系は/myapp/.env.productionに書いています。
ディレクトリ構成が下記になっているので適宜変更してください。
/ ├─ myapp/ (Next.jsアプリ) │ ├─ app/ │ │ └─ page.tsx │ ├─ .env.production │ ├─ next.config.ts │ ├─ package.json │ ├─ package.lock.json │ ├─ server.js │ └─ tsconfig.json └─ docker-compose.yml
自前でserver.jsを用意します
/* eslint-disable @typescript-eslint/no-require-imports */
// server.js
const express = require("express");
const next = require("next");
const path = require("path");
const port = parseInt(process.env.PORT || "3000", 10);
const dev = process.env.NODE_ENV !== "production";
const app = next({ dev });
const handle = app.getRequestHandler();
app.prepare().then(() => {
const server = express();
// 最大アップロードサイズを設定
server.use(express.json({ limit: "500mb" }));
server.use(express.urlencoded({ extended: true, limit: "500mb" }));
server.use(
"/_next/static",
express.static(path.join(__dirname, ".next/static"))
);
server.all("*", (req, res) => {
return handle(req, res);
});
server.listen(port, () => {
console.log(`> Ready on http://localhost:${port}`);
});
});
# Dockerfile
FROM node:20-alpine AS base
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
FROM node:20-alpine AS builder
WORKDIR /app
COPY --from=base /app/node_modules ./node_modules
COPY . .
RUN npm run build
# 本番用
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
COPY --from=builder /app/public ./public
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json
COPY --from=builder /server.js ./server.js
# Next standalone実行に必要
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
EXPOSE 3000
CMD ["node", "server.js"]
services:
app:
build:
context: ./myapp
dockerfile: Dockerfile
container_name: myapp-app
restart: unless-stopped
ports:
- "3000:3000"
environment:
- NODE_ENV=production
env_file:
- ./myapp/.env.production
depends_on:
- db
volumes:
postgres_data:
あとはNginx側でもclient_max_body_sizeを設定してあげます。
server {
listen 32222 ssl;
ssl_certificate /home/owner/system/pem/server_cert.pem;
ssl_certificate_key /home/owner/system/pem/server_key.pem;
client_max_body_size 500m; # ここで上限設定
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}