Nginxを使う上で、押さえておきたいと思ったポイントを紹介します。基本的な設定、TLS/SSLの利用、PHP-FPMとの連携などについて取り上げています。
インストール・起動
CentOS7.2上にNginxをインストールします。
yum install epel-release
yum install nginx
バージョンを確認します。
- 1.9.5
- HTTP/2がサポートされ始める
- 1.9.11
- 動的モジュールがサポートされ始める
よく使うコマンドを示します。
# 起動
systemctl start nginx.service
# 停止
systemctl stop nginx.service
# 設定ファイル再読み込み
nginx -s reload
# 設定ファイル構文チェック
nginx -t
# バージョン確認
nginx -v
デフォルトの設定
設定ファイルは「/etc/nginx」に格納されています。
この中の nginx.conf
がベースとなる設定ファイルです。nginx.conf
内で他の設定ファイルをincludeしています。
$ grep include nginx.conf
include /usr/share/nginx/modules/*.conf;
include /etc/nginx/mime.types;
# See http://nginx.org/en/docs/ngx_core_module.html#include
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/default.d/*.conf;
# include /etc/nginx/default.d/*.conf;
/usr/share/nginx/modules
配下にも設定ファイルがあるようです。動的モジュールの設定ファイルになります。
nginx/1.9.11で動的モジュールがサポートされました。以前は静的モジュールのみしか対応してなかったため、モジュールの追加を行うたびにnginxバイナリをビルドし直す必要がありました。
nginx.conf
のデフォルトの記述は以下のようになっていました。
# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
# Settings for a TLS enabled server.
#
# server {
# listen 443 ssl http2 default_server;
# listen [::]:443 ssl http2 default_server;
# server_name _;
# root /usr/share/nginx/html;
#
# ssl_certificate "/etc/pki/nginx/server.crt";
# ssl_certificate_key "/etc/pki/nginx/private/server.key";
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 10m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
#
# # Load configuration files for the default server block.
# include /etc/nginx/default.d/*.conf;
#
# location / {
# }
#
# error_page 404 /404.html;
# location = /40x.html {
# }
#
# error_page 500 502 503 504 /50x.html;
# location = /50x.html {
# }
# }
}
設定の構成
設定の階層構造
nginx.conf
に記述する設定は、以下のような階層構造になっています。
# mainコンテキスト
events {
# eventsコンテキスト
}
http {
# httpコンテキスト
server {
# serverコンテキスト
listen 80 default_server;
server_name _;
location / {
# locationコンテキスト
}
}
server {
# serverコンテキスト
listen 443 ssl http2 default_server;
server_name _;
location / {
# locationコンテキスト
}
}
}
コンテキスト | 概要 |
---|---|
main | Nginx動作全般の設定 |
events | Eventsモジュールの設定(最大コネクションなど) |
http | HTTP_XXXモジュールの設定(Webサーバとしての設定) |
server | バーチャルホストの設定 |
location | URIに応じた設定 |
バーチャルホスト
1台で複数のWebサイトを動作させるためのものです。Nginxでは、1台で1つのWebサイトを動作させるときにもバーチャルホストを利用します。
バーチャルホストを区別するには、2種類の方法があります。
- 名前ベース
- ドメイン名で区別
- IPベース
- IPやポートで区別
IPベース
と 名前ベース
を組み合わせて区別する場合、 IPベース
の条件が先に判断されます。
コンテキストとディレクティブ
serverディレクティブはhttpコンテキスト内にある といった形で言います。
ディレクティブごとに、指定できるコンテキストは決まっています。
https://nginx.org/en/docs/ 内の Modules reference
から各ディレクティブが利用できるコンテキストを確認できます。例えば、indexディレクティブは以下のように記述されています。
Syntax: index file ...;
Default: index index.html;
Context: http, server, location
indexディレクティブ
は httpコンテキスト
serverコンテキスト
locationコンテキスト
内で使用できるようです。
ファイル分割
下記のように、バーチャルホストごとに設定ファイルを分割すると管理しやすくなります。
# mainコンテキスト
events {
# eventsコンテキスト
}
http {
# httpコンテキスト
include /etc/nginx/conf.d/*.conf;
}
server {
# serverコンテキスト
listen 80 default_server;
server_name _;
location / {
# locationコンテキスト
}
}
server {
# serverコンテキスト
listen 443 ssl http2 default_server;
server_name _;
location / {
# locationコンテキスト
}
}
変数
設定パラメータとして変数を利用できます。ログを残すときなどに便利です。
変数 | 概要 |
---|---|
$hostname | ホスト名 |
$remote_addr | クライアントアドレス |
$request_method | リクエストHTTPメソッド |
$time_local | 現在時刻 |
$uri | 正規化済みURI |
そのほかの変数は、https://nginx.org/en/docs/varindex.html で確認できます。
単位
設定パラメータとして利用できる単位は、以下の通りです。
サイズ
単位 | 値 |
---|---|
k | キロバイト |
m | メガバイト |
時間
単位 | 値 |
---|---|
ms | ミリ秒 |
s | 秒 |
m | 分 |
h | 時 |
d | 日 |
w | 週 |
M | 月 |
y | 年 |
主なディレクティブ
基本設定
下記設定ファイルのディレクティブについてみてみます。
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
keepalive_timeout 65;
server_tokens off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
charset utf-8;
client_max_body_size 32m;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
}
ディレクティブ | 概要 | デフォルト | コンテキスト |
---|---|---|---|
user | nginxの実行ユーザを設定。 | user nobody nobody; | main |
worker_processes | nginxのworkerプロセスの数を設定。通常はCPUコア数以下。autoにすると自動でコア数を検出し同じ数にする。 | worker_processes 1; | main |
error_log | エラーログの出力先を設定。 | error_log logs/error.log error; | main, http, mail, stream, server, location |
pid | PIDファイルの出力先を設定。 | pid nginx.pid; | main |
worker_connections | 1つのworkerプロセスが同時に処理できる最大コネクション数を設定。 | worker_connections 512; | events |
use | コネクションの処理方式を設定。デフォルトでシステムに最適なメソッドを選択するため指定する必要はない。 | – | events |
log_format | アクセスログの書式を設定。 | log_format combined “…”; | http |
access_log | アクセスログの出力先とログフォーマットを設定。 | access_log logs/access.log combined; | http, server, location, if in location, limit_except |
sendfile | ONにするとパフォーマンス向上。vagrantの場合はOFFにしないと不具合が発生する場合がある。 | sendfile off; | http, server, location, if in location |
tcp_nopush | ONにするとパフォーマンス向上。sendfileがONである必要あり。 | tcp_nopush off; | http, server, location |
keepalive_timeout | タイムアウト時間を設定。 | keepalive_timeout 75s; | http, server, location |
server_tokens | nginxバージョン情報の表示設定。 | server_tokens on; | http, server, location |
default_type | レスポンスのデフォルトのMIMEタイプを設定。 | default_type text/plain; | http, server, location |
charset | デフォルト文字コードを設定。 | charset off; | http, server, location, if in location |
client_max_body_size | 受信可能なリクエストボディの最大サイズを設定。デフォルトの1mだと小さいため、ファイルアップロードなどできなくなる可能性あり。 | client_max_body_size 1m; | http, server, location |
listen | IPアドレスやポートを設定。 | listen *:80 | *:8000; | server |
server_name | ホスト名を設定。 | server_name “”; | server |
root | ドキュメントルートを設定。 | root html; | http, server, location, if in location |
error_page | レスポンスコードに対応するエラーページを設定。 | – | http, server, location, if in location |
TLS/SSL
下記バーチャルホストの設定では、HTTPでアクセスがきたとき、HTTPSのURLにリダイレクトするようにしています。
server {
listen 80 default_server;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
server_name _;
root /usr/share/nginx/html;
ssl_certificate "/etc/pki/nginx/server.crt";
ssl_certificate_key "/etc/pki/nginx/private/server.key";
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
ディレクティブ | 概要 | デフォルト | コンテキスト |
---|---|---|---|
return | 処理を停止して、クライアントに返すコードを設定。 | – | server, location, if |
ssl_certificate | 証明書のファイルパスを設定。 | – | http, server |
ssl_certificate_key | 秘密鍵のファイルパスを設定。 | – | http, server |
ssl_session_cache | SSLセッションをキャッシュするか設定。キャッシュすることでサーバ負荷軽減。 | ssl_session_cache none; | http, server |
ssl_session_timeout | キャッシュのタイムアウトを設定。 | ssl_session_timeout 5m; | http, server |
ssl_prefer_server_ciphers | ONにするとサーバ側が示した暗号化スイートを優先。OFFにするとクライアント優先。 | ssl_prefer_server_ciphers off; | http, server |
ssl_ciphers | HTTPSで利用する暗号化スイートのリストを設定。「https://wiki.mozilla.org/Security/Server_Side_TLS」で最新のリストを確認して設定する。 | ssl_ciphers HIGH:!aNULL:!MD5; | http, server |
ssl_protocols | HTTPSで利用するプロトコルを設定。 | ssl_protocols TLSv1 TLSv1.1 TLSv1.2; | http, server |
PHP-FPMと連携
PHP-FPMと連携するには、FastCGIプロトコル
を利用します。
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
fastcgi_buffer_size 16k;
fastcgi_buffers 4 16k;
fastcgi_connect_timeout 75s;
fastcgi_send_timeout 75s;
fastcgi_read_timeout 75s;
}
}
10〜12行目
このバーチャルサーバの設定では、まず、phpファイルが指定されたリクエストは14〜27行目のlocationで処理されます。そのほかのリクエストは10〜12行目で処理されます。
Laravel
や WordPress
では、index.phpが全てのリクエストを受け付けるフロントコントローラとして機能し、ここからコアとなる処理が始まります。そのため、try_files
を利用して、ファイルパスが存在しないURIを index.php
のパラメータとして渡されるようにしています。
- 判定順序
- 1
.phpファイル
が指定されたリクエストは14〜27行目で処理。 - 2
.php以外
のリクエストは10〜12行目で処理。- 2-1 存在するファイルパスであればその内容を返す。
- 2-2 存在しないファイルパスであればリダイレクト。リダイレクト先は
/index.php?$query_string
- 1
15行目
(.+\.php)
の部分が $fastcgi_script_name
の値になります。(/.+)
の部分が $fastcgi_path_info
の値になります。
20行目
PHP-FPMとの接続方法は2通りあります。
# TCP接続(同一サーバ上でデフォルト設定でPHP-FPMを起動している場合)
fastcgi_pass 127.0.0.1:9000;
# UNIXドメインソケットによる接続
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
UNIXドメインソケットを利用する方が、TCP接続より負荷が低いです。しかし、NgnixとPHP-FPMが同一サーバ内で起動している時しか利用できません。TCP接続ですと、NginxとPHP-FPMが異なるサーバで起動していても利用できます。
ディレクティブ | 概要 | デフォルト | コンテキスト |
---|---|---|---|
fastcgi_split_path_info | リクエストURIを分割して、$fastcgi_script_nameと$fastcgi_path_infoに値を設定するための正規表現を設定。 | – | location |
fastcgi_index | $fastcgi_script_nameの値を設定。 | – | http, server, location |
fastcgi_param | リクエストに付与するパラメータを設定。 | – | http, server, location |
fastcgi_pass | 転送先を設定。 | – | location, if in location |
fastcgi_buffer_size | FastCGIの応答の最初の部分を読み取るために使用されるバッファサイズを設定。 | fastcgi_buffer_size 4k|8k; | http, server, location |
fastcgi_buffers | FastCGIの応答を読み取るために使用されるバッファ数とサイズを設定。 | fastcgi_buffers 8 4k|8k; | http, server, location |
fastcgi_connect_timeout | FastCGIと接続を確立するためのタイムアウトを設定。 | fastcgi_connect_timeout 60s; | http, server, location |
fastcgi_send_timeout | FastCGIに要求を送信するためのタイムアウトを設定。 | fastcgi_send_timeout 60s; | http, server, location |
fastcgi_read_timeout | FastCGIからの応答を受信するためのタイムアウトを設定。 | fastcgi_read_timeout 60s; | http, server, location |
try_files | 指定したファイルパスが存在しない場合、最後に指定したURIにリダイレクトする。 | – | server, location |