メインコンテンツまでスキップ

初心者のためのNGINX

· 約10分

本ブログでは、NGINXの基本的な利用シーンである静的ホスティングリバースプロキシロードバランサについてまとめます。

また、それぞれのユースケースについて、Dockerを使った完全に再現可能な構成セットアップを提供します。

NGINXとは?

NGINXは、静的ホスティングリバースプロキシロードバランサHTTPキャッシュとして使用できる人気のWebサービス・ミドルウェアです。

FreeBSDライセンスによるオープンソースソフトウェアです。

NGINXはなぜ人気なのか?

ChatGPTは以下のように答えています(太字は著者):

NGINXが人気なのはいくつかの理由があります:

  1. ハイパフォーマンスとスケーラビリティ: NGINXは、その高いパフォーマンスとスケーラビリティで知られており、少ないリソース消費で数千の同時接続を処理することが可能です。このため、トラフィックの多いWebサイトやWebアプリケーションに最適です。

  2. Easy to Configure and Customize: NGINXはシンプルで直感的な設定システムを備えており、特定のユースケースに合わせたカスタマイズや最適化が容易に行えます。また、モジュールやプラグインのエコシステムも充実しており、機能を拡張することができます。

  3. Reliability and Stability: NGINXは信頼性と安定性に優れ、クラッシュや故障の発生率が低いです。イベント駆動型の非同期アーキテクチャを採用し、複数の接続を効率的に処理し、障害から自動的に回復するように設定することが可能です。

  4. Security: NGINXには、SSLやTLSによる暗号化、アクセス制御、DDoS対策など、いくつかのセキュリティ機能が組み込まれています。また、サードパーティのセキュリティツールやサービスとの統合もサポートしています。

  5. オープンソースとコミュニティサポート: NGINXはオープンソースソフトウェアであり、自由に利用でき、誰でも変更・配布できることを意味します。また、開発者やユーザーからなる大規模で活発なコミュニティがあり、開発、文書化、サポートに貢献しています。

リファレンス: https://www.nginx.com/resources/glossary/nginx/

補足ですが、オープンソースソフトウェアの全てが何の制限もなく改変して配布できるわけではありません。 ただ、NGINXのライセンス(FreeBSD)は非常に寛容なライセンスの1つなため、可能です。

Dockerを使ったセットアップ

ユースケースに入る前に、Dockerのインストールとデモ用リポジトリのクローンを作成してください。

インストール

ここではDockerを使用しますので、まだインストールされていない方はインストールをお願いします。

MacWindowsの方は、Docker Desktop(個人または中小規模の企業であれば無料)かRancher Desktop(無料で商用利用可)をダウンロードすることをお勧めします。 これらのソフトウェアには、Dockerが動作するLinux VMをインスタンス化するための仮想マシンが付属しています。

Linuxの場合、パッケージマネージャを使ってdockerコマンドをインストールすることができます。

インストールを確認する

  1. ターミナルを開き、docker run --rm -p 8080:80 nginxを実行し、公式イメージからNGINXコンテナを起動する。
  2. 次に、ブラウザを開き、http://localhost:8080/にアクセスします。
  3. 「Welcome to nginx!」というページが表示されれば、インストールとセットアップは成功です。

Ctrl-Cで実行中のコンテナを停止させることができます。

これらのオプションは何を意味するのか?
  • --rm: 停止したコンテナを削除します。
  • -p 8080:80: 8080 ローカルと 80 コンテナ間のポートマッピングを設定します。

デモコードのダウンロード

ターミナルで git clone https://github.com/ryojp/nginx-intro を実行し、リポジトリをクローンしてください。

ユースケース

静的ホスティング

静的ホスティングについて深く掘り下げるのはやめましょう。ここでは、いくつかの基本的な使い方の説明に留めます (ご了承ください)。

デモ

  1. クローンしたリポジトリの static_hosting ディレクトリに移動し、docker compose up --build を実行します。
  2. ブラウザで http://localhost:8080 を開いてください。

設定

server {
listen 80;
server_name localhost;

location / {
root /usr/share/nginx/html;
index index.html index.htm;
}

error_page 404 /404.html;

error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
Details

解説 これは、ポート 80 でリッスンし、/usr/share/nginx/html ディレクトリからコンテンツを提供する Web サーバーをセットアップする基本的な NGINX の設定です。

listenディレクティブは、NGINXがリッスンするIPアドレスとポート番号を指定します。この場合、HTTPトラフィックのためにポート80でリッスンします。

server_nameディレクティブは、サーバーのホスト名を指定します。この場合、localhostに設定されています。

locationディレクティブは、特定のURLパターンに一致するリクエストをNGINXがどのように処理するかを定義するために使用されます。この場合、ルート / URL にマッチするリクエストは、/usr/share/nginx/html ディレクトリからファイルが提供され、デフォルトのファイルとして index.html または index.htm が提供されます。

error_pageディレクティブは、特定のエラーが発生した場合に、どのHTMLファイルを提供するかを指定します。この場合、404 Not Foundエラーには/404.html500, 502, 503, 504エラーには/50x.htmlを提供するように設定されています。2番目のlocationブロックは、/50x.htmlファイルの場所を指定します。

全体として、この設定は、指定されたディレクトリから静的ファイルを提供し、一般的なHTTPエラーを処理する単純なWebサーバーを設定します。

リバースプロキシ

NGINXをリバースプロキシとして設定することも非常にシンプルで簡単です。 NGINX設定ファイルは以下のとおりです。

server {
listen 80;
#listen [::]:80;
server_name localhost;

#access_log /var/log/nginx/host.access.log main;

location /hello {
proxy_pass http://hello:8000/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

proxy_passディレクティブを使用することで、上記の設定は /helloエンドポイントでのリクエストをhelloホストのポート 8000 に渡すよう NGINX に指示しています。 デフォルトでは、リバースプロキシによってHostヘッダが変更されるため、proxy_set_headerディレクティブを使用してHost フィールドを元のホストで明示的に上書きするのが一般的な方法です。 最後に、X-Forwarded-For`ヘッダはプロキシされたすべてのホストを含むように設定されます。

デモ

  1. クローンしたレポの reverse_proxy ディレクトリに移動し、docker compose up --build を実行します。
  2. curl http://localhost:8080/hello または curl http://localhost:8080/bye を実行すると、プロキシされたバックエンドからのリクエストが受信できていることが確認できます。

ロードバランサー

上流サーバを定義することで、NGINXはロードバランサーとして機能することができます。

アルゴリズム

NGINXは、ラウンドロビン最小接続数最小時間IPハッシュなど、主要なアルゴリズムをサポートしています。 上記のほとんどは重みを設定することができ、上流のサーバーのマシンスペックが異なる場合に便利です。

NGINX Plusでは、ロードバランシングアルゴリズムに関係なく、ユーザーセッションを識別し、トラフィックを適切な上流に固定することが可能です。

タイムアウト

NGINXでは、クライアントとNGINXの間、NGINXと上流サーバの間の両方で、さまざまなタイムアウトを提供しています。 例えば、proxy_connect_timeoutは、上流サーバとの接続を確立するためのタイムアウトである。 proxy_send_timeout`は、上流サーバにリクエストを送信する際のタイムアウトです。

これらのタイムアウトは、本番環境ではオーバーヘッドを減らすために適切に設定する必要があります。

Example

upstream greetings {
least_conn;
server hello:8000 weight=2;
server bye:8000 weight=1;
}

server {
listen 80;
server_name localhost;

location / {
proxy_pass http://greetings/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

上記のNGINXの設定では、hello:8000bye:8000からなるgreetings上流サーバ群を、重みを変えながら宣言しています。 この上流サーバ群は、リクエストのバランスを取るために重み付けされた最小接続アルゴリズムを使用します。

定義された greetings 上流サーバ群は、 proxy_pass ディレクティブを使用して / へのリクエストのターゲットプロキシとして使用されます。

まとめ

今回は、NGINXの基本的な使い方として、静的ホスティング、リバースプロキシ、ロードバランサーについて見てきました。

NGINXでHTTPキャッシュを設定する方法については、後日改めてブログを書こうと思っています。