ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
この記事の要点
next buildしてからnext startで動かす Node.js サーバー方式が基本。全機能が使える。- Docker でまとめるなら
output: "standalone"。実行に必要な最小構成だけが出力される。 NEXT_PUBLIC_付きの環境変数はビルド時にコードへ埋め込まれる。実行時に切り替えたい値には使えない。- 複数インスタンスで動かすなら、暗号鍵・デプロイ ID・共有キャッシュの 3 点セットを揃える。
- リバースプロキシがレスポンスをためこむとストリーミングが機能しない。バッファリングを切る。
開発が終わったら本番環境に出します。Next.js は Node.js が動く環境なら基本的にどこでも動きますが、キャッシュや環境変数の扱いに独特の前提があり、そこを知らないと「ローカルでは動くのに本番でおかしい」という状態になります。この記事では自前サーバーで運用する場合を中心に扱います。
1デプロイ方式の選択
| 方式 | 使える機能 | 向いている場面 |
|---|---|---|
| Node.js サーバー | すべて | VPS・専用サーバーでの通常運用 |
| Docker コンテナ | すべて | コンテナ基盤、環境の再現性を重視する場合 |
| 静的書き出し | 制限あり | サーバーを持てない環境、純粋な静的サイト |
静的書き出し(output: "export")は HTML と静的ファイルだけを出力する方式で、任意の Web サーバーに置けます。ただしサーバーを必要とする機能は使えません。proxy.ts のようにリクエストを見る仕組みは動かず、画像最適化も専用のローダーを別途用意する必要があります。
2Node.js サーバーとして動かす
npm run build
npm run start
これだけで全機能が使えます。ただし、Next.js のサーバーを直接インターネットに晒すのは推奨されていません。Nginx などのリバースプロキシを前段に置き、不正なリクエストの遮断、接続数の制限、ペイロードサイズの上限といった役割を任せます。Next.js 側は描画に専念させる、という考え方です。
3Docker 向けの standalone 出力
コンテナに入れる場合、node_modules を丸ごと持ち込むとイメージが肥大します。output: "standalone" を指定すると、実行に必要なファイルだけがまとめて出力されます。
// next.config.ts
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
output: 'standalone',
}
export default nextConfig
複数のコンテナを立てる場合、同じビルド成果物を使い回すのが原則です。ステージごとにビルドし直すと、後述するビルド ID が食い違って問題が起きます。どうしてもビルドを分ける必要があるなら、generateBuildId で git のコミットハッシュなどを固定値として与えます。
// next.config.js
module.exports = {
generateBuildId: async () => {
return process.env.GIT_HASH
},
}
4環境変数はいつ読まれるか
ここが最も誤解されやすい部分です。環境変数には、ビルド時に固定されるものと、実行時に読まれるものがあります。
実行時に確実に読みたい場合は、connection() を先に await します。これによりその処理がリクエスト時の実行に切り替わり、ビルド時の値が固定されるのを防げます。
import { connection } from 'next/server'
export default async function Page() {
await connection()
const value = process.env.RUNTIME_CONFIG // 実行時に評価される
return <p>{value}</p>
}
なお、バージョン 16 で serverRuntimeConfig と publicRuntimeConfig は削除されました。環境変数に置き換えてください。
5キャッシュの置き場所
生成済みページやキャッシュは、既定でインスタンスごとのメモリとローカルディスクに保存されます。1 台で動かし、ディスクが永続化されているなら、これで問題ありません。
問題になるのは複数台構成です。コンテナごとに別々のキャッシュを持つため、あるインスタンスで再検証しても他には伝わらず、古い内容が出続けます。この場合は共有ストアを使うカスタムのキャッシュハンドラを設定します。
// next.config.js
module.exports = {
cacheHandler: require.resolve('./cache-handler.js'),
cacheMaxMemorySize: 0, // 既定のメモリキャッシュを無効化
}
ハンドラ側では get / set / revalidateTag を実装し、Redis などの外部ストアに保存します。加えて、タグの無効化を全インスタンスへ伝えるための refreshTags も実装しておくと、再検証の取りこぼしを防げます。
6複数インスタンスで必要な 3 点
| 項目 | 設定するもの | 怠るとどうなるか |
|---|---|---|
| 暗号鍵 | NEXT_SERVER_ACTIONS_ENCRYPTION_KEY | 「Server Action が見つからない」エラーが散発する |
| デプロイ ID | deploymentId | ローリング更新中に古い資産を要求して失敗する |
| 共有キャッシュ | cacheHandler | インスタンスごとに表示内容がずれる |
暗号鍵はビルドごとに自動生成されるため、インスタンス間で食い違うと Server Function の復号に失敗します。base64 で 16・24・32 バイトのいずれかの鍵を用意し、ビルド時に環境変数で与えます。
デプロイ ID を設定すると、静的資産の URL にデプロイ識別子が付き、クライアントの持つ ID と食い違ったときは通常のページ遷移ではなく完全な再読み込みに切り替わります。新旧のバージョンが混在する時間帯を安全に乗り切るための仕組みです。
7ストリーミングを止めない
ストリーミングは、レスポンスを分割して送り続けることで成立します。前段のプロキシがバッファリングしていると、分割の意味が失われて最後にまとめて届きます。
// next.config.js
module.exports = {
async headers() {
return [
{
source: '/:path*{/}?',
headers: [{ key: 'X-Accel-Buffering', value: 'no' }],
},
]
},
}
ロードバランサーやその手前の機器も、分割転送に対応している必要があります。1 か所でもためこむ設定があると、経路全体でストリーミングが無効になります。
8停止と再起動
after() で登録した後処理は、レスポンスを返した後に実行されます。プロセスを止めるときは SIGINT か SIGTERM を送り、処理中のリクエストと保留中の後処理が終わるのを待ちます。停止までの猶予は 10〜30 秒程度を確保しておくのが目安です。いきなり強制終了すると、書き込み途中の処理が失われる可能性があります。
9つまずきやすいところ
- 環境変数を変えたのに反映されない:
NEXT_PUBLIC_付きはビルド時に埋め込まれます。再ビルドが必要です。 - CDN を挟んだら個人情報が他人に見えた:リクエスト依存の描画では
Cache-Control: privateが付きますが、CDN 側がこれを尊重する設定になっているか確認してください。 - 画像最適化でメモリを食う:glibc 系の Linux では、メモリアロケータの設定が必要になる場合があります。
- ビルドが Webpack 設定で失敗する:バージョン 16 では Turbopack が既定です。設定を移行するか
--webpackを指定します。 - デプロイ直後だけ遅い:キャッシュキーにビルド ID が含まれるため、新しいデプロイでは作り直しから始まります。仕様どおりの挙動です。
これでひととおりの流れが揃いました。最後に、既存プロジェクトをバージョン 16 へ持っていく際の注意点をまとめます。
ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
子ページはありません
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript で base URL を取得する方法|window.location.origin
- 4 YouTube Data API v3 エラー一覧|403・400・404 の原因と対処
- 5 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 6 Spring Frameworkのアノテーション一覧
- 7 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- PHPでのファイルアップロード方法|multipart/form-dataと$_FILES 2026-08-07 17:15:57
- PHP $_SERVERとは|DOCUMENT_ROOT・PHP_SELFなど主な要素 2026-08-07 17:15:57
- Scratchのアカウントの作り方|メールアドレスとユーザー名の登録手順 2026-08-07 17:15:57
- djangoにおけるMVCアプリケーション実装例 2026-08-07 17:15:57
- Bluetoothとは|仕組み・BLEとClassicの違い・用途 2026-08-07 17:15:57
- Spring Bootのテスト入門|@SpringBootTestとJUnitでの単体・結合テスト 2026-08-07 17:15:57
- Java とは?言語仕様・JVM・主要フレームワーク一覧 2026-08-07 17:15:56
- インストール方法(Windows版) 2026-08-07 17:15:56
- APIキー取得方法 2026-08-07 17:15:56
- 【PHPフレームワーク】Laravelの使い方 2026-08-07 17:15:56
- Scratch 作品の公開方法 2026-08-07 17:15:56
- Google OAuth 2.0 認証の実装方法 2026-08-07 17:15:56
- データベースとは?RDB / NoSQL / SQL の基礎 2026-08-07 17:15:56
- インストール(eclipseプラグイン) 2026-08-07 17:15:56
- Spring Frameworkの使い方 2026-08-07 17:15:56
コメントを削除してもよろしいでしょうか?