Nginx の設定概要

Written by @dr_taka_n at 2012/03/11 13:30 [, ]

Nginx に関して、とりあえず最初の一歩としてこれだけ知っておけば何とかなる、という内容をまとめておきたくメモを残すことにした。

Basic Nginx Configuration – Linode Library のページがとてもよくまとめられていたので、このページの内容をベースに書かせてもらった。

  • 全体的な構成
  • グローバルな設定
  • サーバの設定 - server ディレクティブ
    • listen ポートの設定 - listen ディレクティブ
    • バーチャルホストの設定 - server_name ディレクティブ
    • リソース(ロケーション)の設定 - location ディレクティブ
  • 設定ファイルの管理

全体的な構成

Nginx の設定に関しては、まずは、ディレクティブブロックコンテキストという言葉をおさえておく。

Nginx はインストール直後ですぐに使える状態になっており、設定は $NGINX_ROOT/conf/nginx.conf に記載されている。($NGINX_ROOTは Nginx がインストールされているルートディレクトリに読み替えること。)

その設定ファイル内のざっくりとした構成は以下のような感じになっている。

#user  nobody;
worker_processes  1;
...
events {
  ...
}

http {
  ...
  server {
    ...
    location / {
      ...
    }
    ...
  }
  ...
}

worker_processeseventshttpserverocation というのがディレクティブであり、eventshttpserverlocation などは{ } (中括弧)で囲まれたブロックを引数に持っている。 このブロックを含めたディレクティブの引数に 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_nameexample.com を定義している。これにより、http://example.com にはこのサーバが応答する。
  • 2つ目の例の example.com www.example.com の場合、http://example.comhttp://www.example.com に応答する。
  • *.example.com.example.com の記述の意味は等しい。また、この記述の場合、サブドメインも全てハンドリングする。例えば、www.example.comimg.example.comsearch.example.com など。
  • 5つ目の例の example.* の記述は、example で始まる全てのドメインへのリクエストをハンドルする。 例えば、example.comexample.netexample.org など。example.wao.comexample.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_nameexample.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 ディレクティブのパターン適用ルールは以下の通りとなる。

  1. 完全一致(=)が最初に処理される。マッチするものが見つかった場合、Nginx はそこでパターンの検索を中止し、リクエストを実行する。
  2. 次に残りのリテラル文字列ディレクティブが処理される。もし、^~ が使用されていれば、Nginx はそこでパターンの検索を中止し、リクエストを実行する。それ以外の場合は、Nginx は location ディレクティブを処理し続ける。
  3. 正規表現で定義された(~~*)全ての location ディレクティブが処理される。正規表現がマッチしたら、Nginx はそこでパターンの検索を中止し、リクエストを実行する。
  4. 正規表現がない、または、正規表現がマッチしなかったときは、最も適切なリテラル文字列のパターンが使用される。

一旦 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 ディレクティブによって、個々のバーチャルホスト毎の設定は別ファイルに定義を行っている。

参考情報

blog comments powered by Disqus