How to Build and Run Next.js Applications with Docker, Compose, & NGINX

DockerCon 2022 で、Sourcegraph のフルスタックエンジニアである Kathleen Juell 氏が、Next.js を組み合わせるためのヒントを共有しました。 Docker、および静的コンテンツを提供するためのNGINX。 現在、約4億のアクティブなWebサイトがあり、効率的なコンテンツ配信は、新しいWebアプリケーションユーザーを引き付けるための鍵です。

場合によっては、Next.js を使用すると、展開効率が向上し、市場投入までの時間が短縮され、Web ユーザーを引き付けることができます。 Docker を使用した Next.js アプリケーションの構築と実行に取り組んでいます。 また、その静的コンテンツを提供するための主要なプロセスと役立つプラクティスについても説明します。 

Webアプリケーションで静的コンテンツを提供する理由

Kathleen 氏によると、静的コンテンツを提供する利点は次のとおりです。 

  • データベースやその他のマイクロサービスなどの可動部分が少ないと、ページのレンダリングに直接影響します。 このバックエンドのシンプルさにより、攻撃対象領域が最小限に抑えられます。 
  • 静的コンテンツは、より高いトラフィック負荷に対して(不確実性が少なく)よりよく立ち上がります。
  • 静的Webサイトは、繰り返しレンダリングする必要がないため、高速です。
  • 静的なWebサイトコードは安定しており、比較的変化しないため、スケーラビリティが向上します。
  • コンテンツがシンプルになるということは、展開オプションが増えることを意味します。

静的 Web アプリの構築が有益である理由はわかっているので、その方法を見ていきましょう。

サービススタックの構築

静的コンテンツを効率的に提供するために、Next.js、 NGINX、およびDockerは便利です。 Next.jsサーバーを実行することは可能ですが、これらのタスクをNGINXサーバーにオフロードすることをお勧めします。 NGINXはイベント駆動型であり、シングルスレッドアーキテクチャのおかげでコンテンツの迅速な提供に優れています。 これにより、トラフィックが多い期間でもパフォーマンスを最適化できます。  

幸いなことに、クロスプラットフォームのNGINXサーバーインスタンスのコンテナ化は非常に簡単です。 この設定はリソースにも優しいです。 以下は、Kathleenが明示的またはおそらく暗黙的に3つのテクノロジーを活用した理由の一部です。 

Docker Desktop には、アプリケーションの構築とデプロイに必要なツールも用意されています。 Kathleen の開発プロセスを再現する前に、 Docker Desktop をインストールする ことが重要です。 

次の3つのサービスは、静的コンテンツを提供します。

まず、 auth-backend ディレクトリとポートマッピングをルートとするビルドコンテキストがあります。 これは、 Node.js Docker公式イメージ のより alpine スリムなフレーバーに基づいており、名前付き Dockerfile ビルドステージを使用して、並べ替え COPY られた命令が壊れるのを防ぎます。 

次に、サービス client には独自のビルド コンテキストと、ディレクトリにマップされた staticbuild:/app/out 名前付きボリュームがあります。 これにより、NGINXコンテナ内にボリュームをマウントできます。 NGINXがコンテンツを提供するため、ポートをマッピングしていません。

第三に、 NGINX Docker 公式イメージに基づく NGINX サーバーをコンテナー化します。

Kathleenが言及しているように、この client サービスを Dockerfile コマンドで RUN 終了することが重要です。 プロセスの完了後 yarn build にコンテナを終了させます。 このプロセスは静的コンテンツを生成し、静的Webアプリケーションに対して一度だけ発生します。

各コンポーネントは、独自のコンテナー内で考慮されます。 では、このマルチコンテナ展開をシームレスにスピンアップし、コンテンツの提供を開始するにはどうすればよいでしょうか。 飛び込みましょう!

Docker Compose ボリュームと Docker ボリュームの使用

複数コンテナーのデプロイを調整する最も簡単な方法は、 Docker Compose を使用することです。 これにより、複数のファイルをジャグリングしたり、複雑なコードを記述したりすることなく、統一された構成内で複数のサービスを定義できます。 

ファイルを使用して compose.yml 、サービス、そのコンテキスト、ネットワーク、ポート、ボリュームなどを記述します。 これらの構成は、アプリの動作に影響します。 

完全な Docker 作成ファイルは次のようになります。 

services:
  auth-backend:
    build:
      context: ./auth-backend
    ports:
      - "3001:3001"
    networks:
      - dev
	
  client:
    build:
      context: ./client
    volumes:
      - staticbuild:/app/out
    networks:
      - dev

  nginx:
    build:
      context: ./nginx
    volumes:
      - staticbuild:/app/public
    ports:
      - “8080:80”
    networks:
      - dev

  networks:
    dev:
      driver: bridge

  volumes:
    staticbuild:

また、このファイルでネットワークとボリュームを定義していることもわかります。 これらのサービスはすべてネットワークを共有する dev ため、検出可能な状態を維持しながら相互に通信できます。 また、これらのサービス間で共通のボリュームも表示されます。 それが重要である理由を説明します。

マウントされたボリュームを使用してファイルを共有する

具体的には、この例では、名前付きボリュームを利用してコンテナー間でファイルを共有します。 ボリュームを staticbuild Next.js の既定の out ディレクトリの場所にマッピングすることで、ビルドをエクスポートし、NGINX サーバーでコンテンツを提供できます。 これは通常、1 つ以上の HTML ファイルとして存在します。 NGINXは app/public 比較によってディレクトリを使用することに注意してください。 

Next.jsはフロントエンドでコンテンツを表示するのに役立ちますが、NGINXはバックエンドからこれらの重要なリソースを提供します。 

A/B テストを活用してカスタマイズされたユーザー エクスペリエンスを作成する

クライアント側のコードをカスタマイズして、アプリの外観を変更し、最終的にはエンド ユーザー エクスペリエンスを変更できます。 このコードは、NGINXサーバーのようなものが実行されている間のページコンテンツの表示方法に影響を与えます。 また、どのユーザーがどのコンテンツを表示するかを決定する場合もあります (たとえば、サインイン状態に基づいて一般的なことです)。 

テストは、アプリケーションの変更がこれらのユーザーエクスペリエンスにプラスとマイナスの両方にどのように影響するかを理解するのに役立ちます。 A / Bテストは、機能とページデザインを比較することにより、アプリケーションの「最良の」バージョンを明らかにするのに役立ちます。 これは実際にはどのように見えますか? 

具体的には、Cookie とフックを使用して、ユーザーのログイン アクティビティを追跡できます。 ユーザーがログインすると、ユーザーストーリーのようなものが表示されます(Kathleenの例から)。 ログアウトしたユーザーには、このコンテンツは表示されません。 または、Web ユーザーは、認証された後にのみ特定のページにアクセスできる場合があります。 ユーザーのアクティビティを監視し、フィードバックを確認し、それらの変更が明確な価値をもたらすかどうかを判断するのはあなたの仕事です。 

これらはA / Bテストの2つのユースケースに過ぎず、Next.jsを使用して静的コンテンツを条件付きでレンダリングする場合、可能性はほぼ無限です。 

次の静的 Web アプリをコンテナー化する.js

静的コンテンツを提供するには、さまざまな方法があります。 しかし、キャスリーンの3サービス方式は依然として優れた例です。 これは、探索的テスト中と運用環境の両方で役立ちます。 詳細については、 キャスリーンの完全な講演をご覧ください。 

各サービスをコンテナー化することで、アプリケーションの柔軟性を維持し、どのプラットフォームにもデプロイできます。 Docker は、開発者が Web アプリケーション内でアクセス可能でカスタマイズ可能なユーザー エクスペリエンスを作成するのに役立ちます。 今すぐ Next.js と Docker を使って、静的なウェブコンテンツの提供を始めましょう! 

関連資料