デプロイ
おめでとうございます。本番環境へのリリース準備が整いました。
あなたはVercelによるマネージドNext.jsをデプロイするか、Node.jsサーバー、Dockerイメージ、または静的HTMLファイルで自己ホスティングできます。next start
を使用してデプロイする場合、すべてのNext.js機能がサポートされます。
本番ビルド
next build
を実行すると、アプリケーションの最適化された本番環境バージョンが生成されます。HTML、CSS、およびJavaScriptファイルは、ページに基づいて作成されます。JavaScriptは**コンパイル**され、ブラウザバンドルはNext.jsコンパイラを使用して**圧縮**されるため、最高の性能を実現し、すべての最新のブラウザをサポートします。
Next.jsは、マネージドと自己ホスティングの両方のNext.jsで使用される標準的なデプロイ出力を作成します。これにより、両方のデプロイ方法ですべての機能がサポートされます。次のメジャーバージョンでは、この出力をBuild Output API仕様に変換する予定です。
VercelによるマネージドNext.js
Vercelは、Next.jsの開発者およびメンテナーであり、Next.jsアプリケーションのためのマネージドインフラストラクチャと開発者エクスペリエンスプラットフォームを提供しています。
Vercelへのデプロイはゼロコンフィグレーションであり、グローバルなスケーラビリティ、可用性、パフォーマンスを向上させるための追加の機能強化を提供します。ただし、自己ホスティングする場合でも、すべてのNext.js機能がサポートされます。
Vercel上のNext.jsの詳細または無料でテンプレートをデプロイして試すことができます。
自己ホスティング
Next.jsは3つの異なる方法で自己ホスティングできます。
🎥 視聴: Next.js のセルフホスティングについて詳しく学ぶ → YouTube (45分)。
Node.js サーバー
Next.js は、Node.js をサポートする任意のホスティングプロバイダーにデプロイできます。`package.json` に `build` スクリプトと `start` スクリプトが含まれていることを確認してください。
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start"
}
}
次に、`npm run build` を実行してアプリケーションをビルドします。最後に、`npm run start` を実行して Node.js サーバーを起動します。このサーバーは、すべての Next.js 機能をサポートしています。
Docker イメージ
Next.js は、Docker コンテナをサポートする任意のホスティングプロバイダーにデプロイできます。Kubernetesなどのコンテナオーケストレーターにデプロイする場合、または任意のクラウドプロバイダーでコンテナ内で実行する場合に、このアプローチを使用できます。
- Docker のインストール をマシンに実行します。
- サンプルのクローン作成(または複数環境のサンプル)
- コンテナのビルド:`docker build -t nextjs-docker .`
- コンテナの実行:`docker run -p 3000:3000 nextjs-docker`
Docker を通じた Next.js は、すべての Next.js 機能をサポートしています。
静的 HTML エクスポート
Next.js は、静的サイトまたはシングルページアプリケーション (SPA) として開始し、後で必要に応じてサーバーを必要とする機能にアップグレードできます。
Next.js はこの静的エクスポートをサポートしているため、HTML/CSS/JS 静的アセットを提供できる任意の Web サーバーにデプロイしてホストできます。これには、AWS S3、Nginx、または Apache などのツールが含まれます。
静的エクスポートとして実行すると、サーバーを必要とする Next.js の機能はサポートされません。詳細はこちら。
知っておくと良いこと
- サーバーコンポーネントは、静的エクスポートでサポートされています。
機能
画像最適化
画像最適化は、`next/image` を使用して、`next start` を使用してデプロイする場合、構成なしでセルフホストで動作します。別個のサービスで画像を最適化することを希望する場合は、画像ローダーを構成できます。
画像最適化は、`next.config.js`でカスタム画像ローダーを定義することで、静的エクスポートで使用できます。画像の最適化は、ビルド時ではなく、実行時に実行されます。
知っておくと良いこと
- glibc ベースの Linux システムでは、画像最適化には追加の構成が必要になる場合があります。過剰なメモリ使用を回避するためです。
- 最適化された画像のキャッシュ動作と TTL の設定方法の詳細については、こちらをご覧ください。
- また、画像の最適化を無効化し、`next/image` を使用することによるその他の利点を維持することもできます。たとえば、画像を別途最適化する場合などです。
ミドルウェア
ミドルウェアは、`next start` を使用してデプロイする場合、構成なしでセルフホストで動作します。受信リクエストへのアクセスが必要なため、静的エクスポートを使用する場合はサポートされません。
ミドルウェアは、アプリケーションのすべてのルートまたはアセットの前に実行される可能性があるため、低遅延を確保するために、使用可能なすべての Node.js API のサブセットであるランタイムを使用します。このランタイムは、「エッジで」実行する必要はなく、単一リージョンのサーバーで動作します。複数のリージョンでミドルウェアを実行するには、追加の構成とインフラストラクチャが必要です。
すべての Node.js API を必要とするロジック(または外部パッケージ)を追加する場合は、レイアウトにサーバーコンポーネントとして移動できます。たとえば、ヘッダーを確認してリダイレクトします。リダイレクトまたは書き換えにヘッダー、Cookie、またはクエリパラメーターを使用することもできます。それでも機能しない場合は、カスタムサーバーを使用することもできます。
環境変数
Next.js は、ビルド時と実行時の両方の環境変数をサポートできます。
デフォルトでは、環境変数はサーバーでのみ使用できます。環境変数をブラウザーに公開するには、`NEXT_PUBLIC_` のプレフィックスを付ける必要があります。ただし、これらの公開環境変数は、`next build` の実行中に JavaScript バンドルにインライン化されます。
動的レンダリング中に、サーバーで環境変数を安全に読み取ることができます。
import { connection } from 'next/server'
export default async function Component() {
await connection()
// cookies, headers, and other Dynamic APIs
// will also opt into dynamic rendering, meaning
// this env variable is evaluated at runtime
const value = process.env.MY_VALUE
// ...
}
これにより、異なる値を持つ複数の環境でプロモーションできる単一の Docker イメージを使用できます。
知っておくと良いこと
- `register` 関数を使用して、サーバーの起動時にコードを実行できます。
- runtimeConfig オプションの使用はお勧めしません。これは、スタンドアロン出力モードでは機能しないためです。代わりに、App Router を段階的に採用することをお勧めします。
キャッシングと ISR
Next.js は、レスポンス、生成された静的ページ、ビルド出力、画像、フォント、スクリプトなどのその他の静的アセットをキャッシュできます。
ページのキャッシュと再検証(Incremental Static Regenerationを使用)は、同じ共有キャッシュを使用します。デフォルトでは、このキャッシュは Next.js サーバーのファイルシステム(ディスク上)に保存されます。これは、Pages と App Router の両方を使用してセルフホスティングする場合に自動的に機能します。
キャッシュされたページとデータを永続ストレージに保存したり、Next.js アプリケーションの複数のコンテナまたはインスタンス間でキャッシュを共有したりする場合は、Next.js キャッシュの場所を構成できます。
自動キャッシング
- Next.js は、真に不変のアセットに `public, max-age=31536000, immutable` の `Cache-Control` ヘッダーを設定します。これは上書きできません。これらの不変のファイルにはファイル名に SHA ハッシュが含まれているため、無期限に安全にキャッシュできます。たとえば、静的画像インポートなどです。画像の TTL は構成できます。
- インクリメンタルスタティックリジェネレーション(ISR)は、
getStaticProps
で再検証する時間(秒単位)を指定することで、Cache-Control
ヘッダーにs-maxage: <getStaticProps での再検証時間>, stale-while-revalidate
を設定します。revalidate: false
を設定した場合、デフォルトで1年間のキャッシュ期間になります。getStaticProps
関数を参照してください。 - 動的にレンダリングされたページは、ユーザー固有のデータがキャッシュされないように、
Cache-Control
ヘッダーにprivate, no-cache, no-store, max-age=0, must-revalidate
を設定します。これは、App Router と Pages Router の両方に適用されます。ドラフトモードも含まれます。
静的アセット
静的アセットを別のドメインまたはCDNでホストする場合は、next.config.js
の assetPrefix
設定 を使用できます。Next.js は、JavaScriptファイルまたはCSSファイルを取得する際にこのアセットプレフィックスを使用します。アセットを別のドメインに分割すると、DNSとTLS解決に余分な時間がかかるという欠点があります。
キャッシュ設定
デフォルトでは、生成されたキャッシュアセットはメモリ(デフォルトは50MB)とディスクに保存されます。Kubernetesなどのコンテナオーケストレーションプラットフォームを使用してNext.jsをホストしている場合、各ポッドにはキャッシュのコピーがあります。デフォルトではキャッシュはポッド間で共有されないため、古いデータが表示されないようにするには、Next.jsキャッシュを設定してキャッシュハンドラーを提供し、メモリ内キャッシングを無効にすることができます。
セルフホスティング時のISR/データキャッシュの場所を設定するには、next.config.js
ファイルでカスタムハンドラーを設定できます。
module.exports = {
cacheHandler: require.resolve('./cache-handler.js'),
cacheMaxMemorySize: 0, // disable default in-memory caching
}
次に、プロジェクトのルートに例えばcache-handler.js
を作成します。
const cache = new Map()
module.exports = class CacheHandler {
constructor(options) {
this.options = options
}
async get(key) {
// This could be stored anywhere, like durable storage
return cache.get(key)
}
async set(key, data, ctx) {
// This could be stored anywhere, like durable storage
cache.set(key, {
value: data,
lastModified: Date.now(),
tags: ctx.tags,
})
}
async revalidateTag(tags) {
// tags is either a string or an array of strings
tags = [tags].flat()
// Iterate over all entries in the cache
for (let [key, value] of cache) {
// If the value's tags include the specified tag, delete this entry
if (value.tags.some((tag) => tags.include(tag))) {
cache.delete(key)
}
}
}
}
カスタムキャッシュハンドラーを使用すると、Next.jsアプリケーションをホストするすべてのポッド間の一貫性を確保できます。たとえば、RedisやAWS S3など、どこにでもキャッシュされた値を保存できます。
知っておくと良いこと
revalidatePath
は、キャッシュタグの上位にある便利なレイヤーです。revalidatePath
を呼び出すと、指定されたページの特別なデフォルトタグを使用してrevalidateTag
関数が呼び出されます。
ビルドキャッシュ
Next.js は next build
の実行中に、提供されているアプリケーションのバージョンを識別するためのIDを生成します。同じビルドを使用して、複数のコンテナを起動する必要があります。
環境の各ステージごとに再構築する場合は、コンテナ間で使用する一貫性のあるビルドIDを生成する必要があります。next.config.js
の generateBuildId
コマンドを使用してください。
module.exports = {
generateBuildId: async () => {
// This could be anything, using the latest git hash
return process.env.GIT_HASH
},
}
バージョンずれ
Next.js はほとんどの バージョンずれ の発生を自動的に軽減し、検出された場合は新しいアセットを取得するためにアプリケーションを自動的に再読み込みします。たとえば、deploymentId
に不一致がある場合、ページ間の遷移はプリフェッチされた値を使用するのではなく、強制的なナビゲーションを実行します。
アプリケーションが再読み込みされると、ページ間のナビゲーション間で永続するように設計されていない場合、アプリケーションの状態が失われる可能性があります。たとえば、URLの状態またはローカルストレージを使用すると、ページの更新後も状態が保持されます。ただし、useState
などのコンポーネントの状態は、そのようなナビゲーションでは失われます。
Vercel は、新しいバージョンがデプロイされた後でも、以前のバージョンのアセットと関数が古いクライアントで使用できることを保証するために、Next.js アプリケーションの追加の スキュー保護 を提供します。
各リクエストで ?dpl
クエリ文字列または x-deployment-id
ヘッダーを使用するように、next.config.js
ファイルで deploymentId
プロパティを手動で設定できます。
ストリーミングとサスペンス
Next.js App Router は、セルフホスティング時に ストリーミングレスポンス をサポートしています。Nginxなどのプロキシを使用している場合は、ストリーミングを有効にするためにバッファリングを無効にするように設定する必要があります。
たとえば、NginxではX-Accel-Buffering
をno
に設定することでバッファリングを無効にできます。
module.exports = {
async headers() {
return [
{
source: '/:path*{/}?',
headers: [
{
key: 'X-Accel-Buffering',
value: 'no',
},
],
},
]
},
}
部分的なプリレンダリング
部分的なプリレンダリング(実験的) はNext.jsでデフォルトで動作し、CDN機能ではありません。これには、(next start
による)Node.jsサーバーとしてのデプロイと、Dockerコンテナの使用が含まれます。
CDNとの使用
Next.jsアプリケーションの前にCDNを使用する場合、動的APIにアクセスすると、ページにはCache-Control: private
レスポンスヘッダーが含まれます。これにより、結果のHTMLページが非キャッシュ可能としてマークされます。ページが完全に静的にプリレンダリングされている場合、ページをCDNでキャッシュできるようにCache-Control: public
が含まれます。
静的コンポーネントと動的コンポーネントの両方を必要としない場合は、ルート全体を静的にし、出力HTMLをCDNにキャッシュできます。動的APIが使用されていない場合、next build
を実行すると、これは自動静的最適化のデフォルトの動作になります。
本番環境チェックリスト
静的エクスポート
マルチゾーン
役に立ちましたか?