Nginx に関して、とりあえず最初の一歩としてこれだけ知っておけば何とかなる、という内容をまとめておきたくメモを残すことにした。
Basic Nginx Configuration – Linode Library のページがとてもよくまとめられていたので、このページの内容をベースに書かせてもらった。
- 全体的な構成
- グローバルな設定
- サーバの設定 -
server
ディレクティブ- listen ポートの設定 -
listen
ディレクティブ - バーチャルホストの設定 -
server_name
ディレクティブ - リソース(ロケーション)の設定 -
location
ディレクティブ
- listen ポートの設定 -
- 設定ファイルの管理
Table of Contents
Open Table of Contents
全体的な構成
Nginx の設定に関しては、まずは、ディレクティブ、ブロック、コンテキストという言葉をおさえておく。
Nginx はインストール直後ですぐに使える状態になっており、設定は $NGINX_ROOT/conf/nginx.conf
に記載されている。($NGINX_ROOT
は Nginx がインストールされているルートディレクトリに読み替えること。)
その設定ファイル内のざっくりとした構成は以下のような感じになっている。
#user nobody;
worker_processes 1;
...
events {
...
}
http {
...
server {
...
location / {
...
}
...
}
...
}
worker_processes
、events
、http
、server
、ocation
というのがディレクティブであり、events
、http
、server
、location
などは{
}
(中括弧)で囲まれたブロックを引数に持っている。
このブロックを含めたディレクティブの引数に Nginx で記載可能なシンタックスを使用して条件文などを混じえてディレクティブを記載していく。
Nginx はネストされたブロックの構文を使用でき、上記のように http
ディレクティブに server
ディレクティブがネストされている構文をとれる。この時、server
ディレクティブは http
ディレクティブのコンテキストにあると言う。
ディレクティブは、コンテキストによって使えるもの、使えないものとがあるので、ドキュメント Modules で確認する。
ドキュメントの記載は以下のように、ディレクティブ名、シンタックス、デフォルト動作、コンテキストの記載があり、その後にそのディレクティブの詳細説明が続く構成となっている。
location
syntax: location [=|~|~*|^~|@] /uri/ { ... }
default: no
context: server
インストール時のオプション、パッケージマネージャー等で多少の違いはあるが、インストール直後の $NGINX_ROOT
ディレクトリ配下は以下の構成となっている。(include
ディレクティブでは起点が nginx.conf
の存在するディレクトリになる。後述。)
$ ll
total 42
drwx------ 2 nginx root 4096 2012-03-04 15:21 client_body_temp
drwxr-xr-x 4 root root 4096 2012-03-10 14:46 conf
drwx------ 2 nginx root 4096 2012-03-04 15:21 fastcgi_temp
drwxr-xr-x 2 root root 4096 2012-03-04 15:14 html
drwxr-xr-x 2 nginx root 4096 2012-03-10 17:22 logs
drwx------ 5 nginx root 4096 2012-03-05 22:30 proxy_temp
drwxr-xr-x 2 root root 4096 2012-03-04 15:14 sbin
drwx------ 2 nginx root 4096 2012-03-04 15:21 scgi_temp
drwx------ 2 nginx root 4096 2012-03-04 15:21 uwsgi_temp
設定内でのパスの指定には、絶対パスと相対パスが使えるが、相対パスを使った場合の起点は、$NGINX_ROOT
となる。
デフォルトの設定ファイルは、 $NGINX_ROOT/conf/nginx.conf.default
として残されており、このファイルを読みながら、Nginx の設定の概要を掴むことにする。
グローバルな設定
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
上記の記載で nginx.conf.default
は始まっている。
#
で始まる行はコメントなので解釈されない。- ディレクティブは変数(例:
worker_processes
,pid
)で始まり、その引数(1,logs/nginx.pid
)、または、連続した引数(logs/error.log notice
)を含む。 - 全てのディレクティブは
;
(セミコロン)で終える。 - ディレクティブにはサブディレクティブを含む(ネストする)ことができる。(上記の
events
のように。)
これらのサブディレクティブは{
}
を使って、コンテキストとスコープを定義する。 - スペースは無視されるので、インデントをうまく使って可読性を上げることができる。
- Nginx は、1 つのマスタープロセスと実際にリクエストを処理する複数のワーカープロセスで動作する。ワーカープロセスは非特権ユーザで動作するが、
user
ディレクティブにはそのユーザを指定できる。worker_processes
には、動作させるワーカープロセスのプロセス数を指定する。
さらに読み進める。
http {
include mime.types;
default_type application/octet-stream;
#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 logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
http
ディレクティブのブロック({
}
)が書かれている。
include
ディレクティブはmime.types
ファイルをインクルードしている。相対パスでの記述になっており、この設定ファイルと同じディレクトリにmime.types
ファイルが存在する。通常、設定ファイルに記載される相対パスは、$NGINX_ROOT
が起点となるが、include
ディレクティブの場合は、nginx.conf
ファイルの存在するディレクトリが起点となる。(Since version 0.6.7 CoreModule::include)
このように設定ファイルを外出してinclude
ステートメントで読み込むことができるので、設定ファイルの可動性はあがり、管理し易くなっている。log_format
をコメントアウトし、要件に合わせたログフォーマットに変更することができる。gzip
ディレクティブはラストマイル環境がよくない場合など効果を発揮するコンテンツの圧縮をオンザフライで実行する。Apache でいうところのmod_deflate
の機能。細かな設定が行えるので、詳細は HttpGzipModule を参照のこと。
access_log
ディレクティブの設定サンプルを見てみる。
access_log logs/example.access.log;
access_log /srv/http/example.org/logs/access.log;
access_log /var/log/nginx/access/example.org;
access_log off;
- 最初の例では、相対パスになっているので、この場合は、ログは
$NGINX_ROOT/logs/example.access.log
に記録される。 - 続く 2 つ目、3 つ目の例では、
access.log
へのフルパスでの指定を行っている。 - ログを残したく無い場合、4 つ目の例のようにオフにすることも可能。(あまりやらないだろうが・・・)
サーバの設定 - server ディレクティブ
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
上記の server
ディレクティブは、http
ディレクティブに内包されている(http
ディレクティブのコンテキストにある)。
server
ディレクティブのブロックはそれぞれのサーバ自体の設定を行うところとなる。
listen ポートの設定 - listen
ディレクティブ
まず listen
ディレクティブだが、上記は 80 番ポートで待機していることを意味する。更に柔軟な記載が行えるようになっているので、詳細は、HttpCoreModule::listen を参照のこと。
バーチャルホストの設定 - server_name
ディレクティブ
server_name
ディレクティブは、名前ベースのバーチャルホストを実現する。
1 つの IP アドレスで待機しているサーバは、リクエストヘッダーの HOST 名に基づいて、複数のドメインのホスティングを行える。
# サンプル1
server_name example.com;
# サンプル2
server_name example.com www.example.com;
# サンプル3
server_name *.example.com;
# サンプル4
server_name .example.com;
# サンプル5
server_name example.*;
# サンプル6
server_name example.com exmaple.net example.org;
# サンプル7
server_name localhost example1 example2;
# サンプル8
server_name "";
上記サンプルは、Basic Nginx Configuration – Linode Library の例から使わせてもらっている。
個々の名前は、スペース区切りで記述できる。Nginx はサーバに対して1つ以上の名前を持たせることができ、特定の server_name
ディレクティブは 1 つ以上の名前のリクエストに応答する。また、ワイルドカードの定義や、正規表現での定義も行える。
- 最初のサンプルは、
server_name
にexample.com
を定義している。これにより、http://example.com
にはこのサーバが応答する。 - 2 つ目の例の
example.com www.example.com
の場合、http://example.com
とhttp://www.example.com
に応答する。 *.example.com
と.example.com
の記述の意味は等しい。また、この記述の場合、サブドメインも全てハンドリングする。例えば、www.example.com
、img.example.com
、search.example.com
など。- 5 つ目の例の
example.*
の記述は、example
で始まる全てのドメインへのリクエストをハンドルする。 例えば、example.com
、example.net
、example.org
など。example.wao.com
、example.hello.com
も同様。 - 6 つ目の
example.com exmaple.net example.org
は 3 つのドメイン全てへのリクエストをハンドルする。 - Nginx は無効なドメイン名でもバーチャルホストとして定義できる。7 つ目の例の
localhost example1 example2
の場合、ホスト名となっているが、Nginx はリクエストの HTTP のヘッダのみを見てリクエストを処理するので、有効なドメイン名である必要はない。ただし、この場合は、hosts ファイルにホスト名が定義されている必要がある。 - 最後の
""
の定義では、Nginx は全てのリクエストを処理することを意味する。
リソース(ロケーション)の設定 - location
ディレクティブ
次に location
ディレクティブ。location
ディレクティブは、クライアントによってリクエストされたロケーションに対する振舞いを定義する。
location
ディレクティブは、そのブロックの前に適用するパターンを記載する。シンタックスは以下の通りとなっており、まずはこの動作概要を掴んでおくことが必要。
location [=|~|~*|^~|@] pattern { ... }
Basic Nginx Configuration – Linode Library の例を利用させていただき、その動作を理解する。
# パターングループ1
location / { }
location /images/ { }
location /blog/ { }
location /planet/ { }
location /planet/blog/ { }
# パターングループ2
location ~ IndexPage\.php$ { }
location ~ ^/BlogPlanet(/|/index\.php)$ { }
# パターングループ3
location ~* \.(pl|cgi|perl|prl)$ { }
location ~* \.(md|mdwn|txt|mkdn)$ { }
# パターングループ4
location ^~ /images/IndexPage/ { }
location ^~ /blog/BlogPlanet/ { }
# パターングループ5
location = / { }
- 最初の 5 つのサンプルはリテラル文字列マッチと言われるもの。ホスト名に続くリクエストの最初のパートにマッチする。
server_name
にexample.com
が設定されており、http://example.com/
へのリクエストがあったとする。この時、”location /
” ディレクティブはこのリクエストにマッチする。Nginx は “most specific match” でリクエストの条件を満たす。http://example.com/planet/blog/
とhttp://example.com/planet/blog/about
へのリクエストは、”location /planet/blog/
” で満たされる。当然、”location /planet/
” でも満たされることになる。- 2 つ目のグループの
~
(チルダ)に続くサンプルでは、Nginx は正規表現での適用を行う。これらの~
だけのマッチ表現は case-sensive (大文字小文字を区別する) になる。最初の例では、IndexPage.php
はマッチするが、indexpage.php
はマッチしない。また、/BlogPlanet
、/blogplanet/
、/blogplanet/index.php
もマッチしない。Nginx は Perl Compatible Regular Expressions (PCRE) を使用している。 - 3 つ目のグループの
~*
の表現は、~
の場合と同じく正規表現でのマッチで、case-insentive (大文字小文字を区別しない)になる。ここでの表現では、特定の拡張子で終わるファイル名に対してどう処理するのかを定義している。最初の例では、.pl、.PL、.cgi、.CGI、.perl、.Perl、.prl、.PrL、何れの拡張子のファイルにも適用される。 - 4 つ目のグループの
^~
の表現は、最初のグループのリテラル文字列マッチのように動作する。注意点として、このマッチ文が適用されると Nginx はパターンの検索を中止する。”^~ /images/IndexPage/
”、”^~ /blog/BlogPlanet/
” パターンでのlocation
ディレクティブは、仮に他にマッチするlocation
ディレクティブが他にあったとしても、このパターンがマッチした時点で使用される。 - 最後の
=
の表現は、リクエストされたパスに完全一致した場合に適用され、マッチした時点で他のパターンの検索を中止する。例えば、最後のサンプルは、http://example.com/
にはマッチするが、http://example.com/index.html
にはマッチしない。
ここまでの記述だけでは、location
ディレクティブの全体の適用順がイマイチ掴みきれない。location
ディレクティブのパターン適用ルールは以下の通りとなる。
- 完全一致(
=
)が最初に処理される。マッチするものが見つかった場合、Nginx はそこでパターンの検索を中止し、リクエストを実行する。 - 次に残りのリテラル文字列ディレクティブが処理される。もし、
^~
が使用されていれば、Nginx はそこでパターンの検索を中止し、リクエストを実行する。それ以外の場合は、Nginx はlocation
ディレクティブを処理し続ける。 - 正規表現で定義された(
~
、~*
)全てのlocation
ディレクティブが処理される。正規表現がマッチしたら、Nginx はそこでパターンの検索を中止し、リクエストを実行する。 - 正規表現がない、または、正規表現がマッチしなかったときは、最も適切なリテラル文字列のパターンが使用される。
一旦 Nginx が特定のリクエストに対してリソースを提供する ”location
” を選択したら、このリクエストに対するレスポンスは、”location
” ディレクティブのブロックによって定義される。
location / {
root html;
index index.html index.htm;
}
ドキュメントルートは、root
ディレクティブによって、html ディレクトリに定義されている。上記は相対パスでの指定なので、実際のディレクトリは、$NGINX_ROOT/html
となる。/blog/includes/style.css
へのリクエストは、他の location
ディレクティブがマッチしていないと想定した場合、$NGINX_ROOT/html/blog/includes/style.css
にあるファイルがリソースの対象となる。root
ディレクティブには絶対パスを指定することもできる。
index
ディレクティブはリクエストがファイル名を含んでいない場合に、ファイルシステムのどのファイルが使用されるべきかを指定する。http://example.com/
へのリクエストは、$NGINX_ROOT/http/index.html
のファイルがリソースの対象となる。複数のファイル名指定されている場合、Nginx は順にそのリストを処理し、存在するファイルにリクエストを適用する。上記の例の場合、index.html
が存在しなければ、index.htm
が使用される。仮にどちらも存在しない場合には、404 メッセーが送出される。
設定ファイルの管理
include
ディレクティブを活用し、ベースとなる $NGINX_ROOT/conf/nginx.conf
には必要最低限の記述のみを行い、各サーバ毎の固有の設定は別ファイルに切り出しておくとメンテナンス性があがる。
例えば、以下のような書き方。$NGINX_ROOT/conf/nginx.conf
の内容は至ってシンプルになる。
user nginx;
worker_processes 4;
pid /var/run/nginx.pid;
events {
worker_connections 768;
# multi_accept on;
}
http {
##
# Basic Settings
##
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;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
gzip_disable "msie6";
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
最後の include
ディレクティブによって、個々のバーチャルホスト毎の設定は別ファイルに定義を行っている。