Nginxについて1から理解したい
プラットフォームユニットの福田です!
最近、Nginxとphp-fpmを使った環境構築をしたんですが、Nginxについての理解が結構浅く、苦労しました。。。
なんとなくはわかるけど、ちゃんとは学習したことがなかったNginxを1から理解し、今後のnginxを利用した環境構築を楽にしちゃおう!ということで、今回はNginxを基礎部分からパパッと振り返れらと思います〜
本記事の目的
・Nginxをなんとなく理解してる人が、1から理解を深めてNginx中級者になる
本記事のゴール
・Nginxの設定ファイルで何をしているのかを理解し、Nginxで動的コンテンツを動かせるようになる
そもそもNginxの役割とは?
NginxはWebサーバーソフトウェアというものになります。Webサーバーソフトウェアとは、インターネットを通じてブラウザなどのクライアントからのリクエストに応答し、HTMLページや画像、データなどを返すソフトウェアのことです。
簡単に言うと、「ブラウザの要求に応えて、必要な情報を届ける役割」を担っています。
例えば、誰かがブラウザで「https://example.com」を開くと、
そのリクエストを受け取り、適切なデータ(HTMLファイルなど)を送り返すのがWebサーバーの仕事です。
Nginxとは?
まずはNginxについて軽くおさらいしましょう!
Nginx(エンジンエックス)は、軽量かつ高性能なWebサーバソフトウェアです。
大量の同時接続を効率よく処理するため、イベント駆動モデルを採用しており、静的ファイルの配信からリバースプロキシ、ロードバランサまで幅広く活用されています。
Nginxの主な特徴は以下の通りです。
- 高性能・低リソース消費:少ないメモリ・CPUリソースで高負荷に耐える。
- イベント駆動アーキテクチャ:リクエストごとにプロセスを作らず、イベントループで多接続を効率的にさばく。
- リバースプロキシ機能:バックエンドアプリケーション(PHP, Node.jsなど)との橋渡し。
- ロードバランサ機能:複数バックエンドへのリクエスト分散が可能。
- 設定ファイルがシンプルで直感的。
Nginxでできること
静的コンテンツの高速配信
HTML、CSS、JavaScript、画像ファイルなどの静的リソースを、高速かつ効率的に配信できます。
特に高トラフィック時でも、安定してレスポンスを返せるのがNginxの強みです。
リバースプロキシによるバックエンド連携
Nginxは、受け取ったリクエストをバックエンドサーバ(たとえばPHPアプリ、Node.jsアプリ)へ中継するリバースプロキシとして動作できます。
これにより、アプリケーション層の負荷分散やセキュリティ向上が可能になります。
ロードバランシング
複数のバックエンドサーバにリクエストを分散するロードバランサ機能も備えています。
ラウンドロビン、IPハッシュ、最小接続数ベースなど、様々な分散戦略が設定可能です。
SSL/TLSの終端
HTTPS通信を行う際、SSL/TLSの処理をNginx側で担当することができます。
これにより、バックエンドサーバにはHTTPで通信を引き継ぎ、負荷を軽減できます。
キャッシュ機能
Nginxにはリクエストやレスポンスをキャッシュする機能があり、バックエンドサーバの負荷をさらに減らすことができます。
静的ページやAPIレスポンスのキャッシュを適切に使えば、パフォーマンスが大きく向上します。
簡単なセキュリティ設定
IPアドレスによるアクセス制限や、Basic認証(簡易ユーザー認証)を設定することも可能です。
また、リクエストサイズ制限や、アクセス頻度制御(レートリミット)なども比較的簡単に実装できます。
NginxとApache
Nginx以外でよく利用されるWebサーバーソフトウェアとしてApacheが挙げられると思います。
これらの違いはどのようなものがあるのでしょうか?以下で見てみましょう。
項目 | Nginx | Apache |
---|---|---|
処理モデル | イベント駆動 | プロセス/スレッド駆動 |
同時接続 | 大量に強い | 増加するとメモリ消費大 |
静的コンテンツ配信 | 高速 | そこそこ |
動的コンテンツ処理 | 直接対応不可(外部プロセス必要) | モジュールで直接処理可能(mod_phpなど) |
設定ファイル | シンプル、直感的 | 柔軟だが複雑になりがち |
拡張性 | リバースプロキシやロードバランサに強い | 多機能(モジュール豊富) |
Apacheの方が拡張性が高く、PHP等動的コンテンツの処理ができるのは強みですが、Nginxの大量同時接続が得意ってところの強みがとてもデカそうです。 | ||
現状、静的コンテンツをNginxで配信し、バックエンドで動的コンテンツを動かす方が望ましそうです。 |
設定ファイルの基本構造
Nginxは設定ファイルからNginxの細かな設定を書いていきます。
Nginxの設定ファイルは一般的にはnginx.confという名前で、基本的には/etc/nginxの中に入れるかと思います。
設定ファイルサンプル
server {
listen 80;
server_name test_server;
location / {
root /usr/www/app;
index index.html
}
error_page 500
location = /error.html {
root /usr/www/app;
}
}
各種設定について
listen(待ち受けポート指定)
サーバーがリクエストを受け付けるIPアドレスとポート番号を指定します。
例
listen 80;
listen 80; → ポート80(HTTP)で待機
ポイント
デフォルトでは全ipを設定できます。
また、IPv6の場合も対応してます。その場合は以下のように鉤括弧をつけて書きます
listen [::]:80;
server_name(ホスト名による振り分け)
リクエストのHostヘッダ(ドメイン名)に応じて、どのserverブロックで処理するかを決めます。
例
server_name example.com www.example.com;
example.com または www.example.com へのリクエストに反応。
ポイント
ワイルドカード(*.example.com)や正規表現マッチも可能です。複数記述することも可能で、一番具体的にマッチしたserver_nameが優先されます。
root(ドキュメントルート)
リクエストに対してファイルを探すベースディレクトリを指定します。
例
root /var/www/html;
/var/www/html/index.htmlが、http://example.com/に対応する。
ポイント:
server {}にもlocation {}にも書くことができます。優先されるのはlocationの方です。パスの最後にスラッシュ(/)を付けるのが一般的です。
index(デフォルトファイル)
ディレクトリにアクセスされたとき、デフォルトで返すファイルを指定します。
例
index index.html index.htm;
ディレクトリにアクセスされた場合、最初に存在するファイルを返す。
location
URLごとのパスの設定ができます。パスに一致した処理はこの中の処理が適用されます。
例
location /test/ {
root /usr/www/app;
}
/test/以下の場合は、rootは/usr/www/appが適用される。
proxy_pass(リバースプロキシ先指定)
受け取ったリクエストを別サーバーに転送します。主にバックエンドアプリケーションと繋ぐ時に使います。
例
location /api/ {
proxy_pass http://backend:3000/;
}
/api/以下のリクエストを、http://backend:3000/に中継。
ポイント
URL末尾の/の有無で転送パスが変わります。
access_log / error_log(ログ設定)
リクエストログ(access_log)やエラーログ(error_log)の出力設定を行います。
例
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log warn;
アクセス履歴とエラー内容をそれぞれ右側のパスのファイルに飛ばす
そのほかの処理について
今回は基本的なnginxの設定を見ていきましたが、nginxを調べてみると、confファイルにはロードバランサの設定や、セキュリティの設定などもできそうです。このようなものはドキュメントをみると他にどんな設定があるのかを確認することができるかと思います。
英語ばっかで辛いです
Nginxを通じてPHPを動かしてみる
先ほども触れたように、NginxではPHPなどの動的コンテンツを実行することができないです。
ではどうすればいいのでしょうか?答えとしてはPHP-FPMと連携を行うことです。
具体的にどのような処理を行なって、PHP-FPMとの連携を行ってるのでしょうか?
そこから見ていき、具体的な繋ぎ方まで見てみましょう!
PHP-FPMとは?
PHP-FPMとは、PHP FastCGI Process Managerの略で、PHPスクリプトをWebサーバーと連携して実行するためのプロセスマネージャーです。
FastGCIというプロトコルを利用して、WebサーバーとPHPの間の橋渡しを行い、効率的にPHPの処理を行います。
一般的にはTCPかUNIXドメインソケットのどちらかで通信を行います。
具体的な繋ぎ方
基本的にはlocationでphpファイルを選択し、fastcgiの設定を行なっていくことになります。
設定方法の例としては以下です。
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
fastcgi_pass
FastCGIサーバー(PHP-FPMなど)の指定を行います。
fastcgi_index
ディレクトリにアクセスされた際のデフォルトのファイルを指定します。
include fastcgi_params
FastCGIの環境変数を設定するファイルを読み込みます。
FastCGIの設定なので、PHPとか関係なく、fastcgiの設定が書かれてるファイルの指定です。
基本的には/etc/nginx/fastcgi_paramsに置いてあります。
fastcgi_param
上記に含まれてない環境変数を設定する際に利用します。
基本的にはFastCGIの設定に書くことができないPHPの設定だったりなど、実際に利用する言語の設定をここに書きます。
TCP接続とUNIXソケット接続について
NginxとPHP-FPMとの通信はTCP接続とUNIXソケット接続で行うことができます。
ではこの2つの接続には具体的にどのような特徴があるのでしょうか?最後に見てきましょう。
UNIXソケット接続
同一サーバ内で通信する場合に高速でオーバーヘッドが少ない通信方法です。
サーバーが1台構成の場合はこちらの接続がおすすめの接続方法です。
ex) fastcgi_pass unix:/run/php/php7.4-fpm.sock;
TCP接続
ネットワーク越しに複数サーバ間でやり取りする場合に使う通信方法です。Dockerコンテナ間通信や、ロードバランサを挟む構成ではこちらを利用することが多いです。
ex) fastcgi_pass 127.0.0.1:9000
他の言語を動かすときはどうする?
Node.js
プロキシを利用することで繋げるので、proxy_passを利用します。
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
結構簡単に接続できますね。
Python
fastCGIではなく、uWSGIを利用して接続するのが一般的です。
location / {
include uwsgi_params;
uwsgi_pass unix:/tmp/uwsgi.sock;
}
こちらもuWSGIを通してやれば簡単に動くので、PHPほど大変ではないです。
こう考えるとPHPの環境構築はかなり大変ですね。。。
まとめ
今回はNginxについて改めて振り返ってみました。
ここら辺ってとりあえず動けばいいやでなんとなくの理解で進めがちですが、しっかり理解した後に改めてみてみると、新しい発見や、改善点などが見えてくるのでいいですね。
サーバー側でエラーになった場合でも、ここら辺覚えておくとエラー対応も簡単にできるのもGoodかもです!
今後のためにも一通り復習できてよかったです。Exactly。
Discussion
すごく勉強になります!
今まで何となくでしか使ってなかったnginxへの解像度が上がりました!