HEARTBEATS

nginx連載4回目: nginxの設定、その2 - バーチャルサーバの設定

   

前回と同様に、nginx.orgのパッケージからインストールしたnginxが提供している設定ファイルをサンプルとして説明を行います。

今回はnginxのバーチャルサーバの設定を確認していきます。なお、「バーチャルサーバ」はApache HTTP Serverで言うところ「バーチャルホスト」のことです。

バーチャルサーバ毎の設定ファイル

nginxの設定ファイルnginx.confに次のような記述を行うことにより、/etc/nginx/conf.dディレクトリにある拡張子がconfであるファイルを読み込みます。

include /etc/nginx/conf.d/*.conf;

このconf.dディレクトリにバーチャルサーバ毎の設定ファイルを置くことにより、その設定ファイルが読み込まれます。nginx.orgのパッケージで提供されているサンプルファイルとしては、default.confとexample_ssl.confの2つがあります。前者が標準的なバーチャルサーバの設定ファイルで、後者がTLS/SSLの設定を行ったバーチャルサーバの設定ファイルです。

なお、includeディレクティブで"*.conf"のようにファイル名のパターンマッチを行うときには、ファイル名が読み込まれる順番が不定であることに注意してください。ソースコード レベルの話をすると、パターンを含む文字列はglob()関数により展開され、ファイル名のリストを返します。このとき、返されるファイル名のリストをソートしないことを示すGLOB_NOSORTフラグを付けてglob()関数が呼ばれているため、返されるファイル名のリストの順番は保証されません。後述しますが、デフォルトサーバを決定するときには記述された順番、すなわち読み込まれた順番が意味を持つため注意してください。

バーチャルサーバの設定

さて、本題のバーチャルサーバの話をしましょう。

ここでは、設定ファイル/etc/nginx/conf.d/default.confをサンプルとしてバーチャルサーバの設定の説明を行います。内容は次の通りです。ただし、コメントアウトしている箇所の一部は省いています。

server {
    listen       80;
    server_name  localhost;

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

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

    location ~ /\.ht {
        deny  all;
    }
}

それでは、それぞれの設定について確認していきましょう。

serverコンテキスト - server

server {
    [serverコンテキスト]
}

serverディレクティブにはバーチャルサーバの設定を記述します。括弧{ }で囲まれた部分がserverコンテキストになります。

複数のバーチャルサーバを運用するときには、IPベースあるいは名前ベースのバーチャルサーバとして区別するわけですが、serverディレクティブ自体ではこの区別を行っていません。serverコンテキストに記述するlistenディレクティブとserver_nameディレクティブにより、この区別を行います。

リクエストの受付ソケット - listen

listenディレクティブにはバーチャルサーバがリクエストを受け付けるIPアドレスやポート番号あるいはUNIXドメイン ソケットを設定します。

IPアドレスを指定するときには"listen IPアドレス"あるいは"listen IPアドレス:ポート"の形式で記述します。

listen IPアドレス:ポート番号;

次のように"listen 192.0.2.1:80"と記述するとIPアドレス192.0.2.1の80番ポートでリクエストを受け付けるようになります。

listen 192.0.2.1:80;

後述するようにポート番号のデフォルト値は80であるため、次のようにポート番号を省略して記述することもできます。

listen 192.0.2.1;

IPアドレスのデフォルト値はすべてのインターフェイス アドレスを意味する"*"であり、ポート番号のデフォルト値は"80"になります。そのため、listenディレクティブを省略すると、次の設定と同じになります。

listen *:80;

この設定は次のそれぞれの設定と同じ意味を持ちます。

listen 80;
listen *;

IPv6の場合は[2001:db8:dead:beef::1]のような角括弧で囲む記法を使います。

listen [2001:db8:dead:beef::1]:80;

UNIXドメイン ソケット

nginxではUNIXドメイン ソケットでもリクエストを受け付けることができます。記述方法は"listen unix:UNIXドメイン ソケットのパス"です。

listen unix:パス;

次のように記述するとUNIXドメイン ソケット/var/run/nginx.sockでリクエストを受け付けるようになります。

listen unix:/var/run/nginx.sock;

バーチャル サーバ名 - server_name

server_nameディレクティブにはバーチャル サーバの名前を設定します。

ウェブブラウザはウェブサーバに対して次のようなリクエストを送ります。

GET / HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:11.0) Gecko/20100101 Firefox/11.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: ja,en-us;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive

このとき、リクエスト先のサーバのホスト名をHost:ヘッダフィールドに指定します。この例では"example.com"というホスト名が指定されています。nginxはこのリクエストを受け取ると、このホスト名がserver_nameディレクティブに設定したサーバ名に一致するserverディレクティブのバーチャルサーバを選び、そのserverディレクティブ内の設定が適応されます。このようにserver_nameディレクティブは名前ベースのバーチャルサーバを設定するために使われます。

それでは、いくつかの指定方法を見ていきましょう。

サーバ名を一つだけ指定するときには次のように記述します。

server_name example.com;

複数のサーバ名を記述するには次のようにスペース区切りで指定します。最初に記述したサーバ名をプライマリサーバ名と呼びます。

server_name example.com www.example.com;

サブドメインに全て一致させるには次のどちらかのように記述します。"*"はすべてのサブドメインに一致します。また、"."で始まる場合も同様です。

server_name *.example.com;
server_name .example.com;

次のように正規表現を使って記述することもできます。

server_name ~^www\d+\.example\.com$;

空を意味する""を設定すると、Host:ヘッダ フィールドがない場合に一致します。なお、server_nameディレクティブのデフォルト値はこの""となっています。

server_name "";

リダイレクト時のサーバ名 - server_name_in_redirect

server_nameに関連するディレクティブにserver_name_in_redirectというものがありますのでこのディレクティブについても確認しましょう。

server_name_in_redirectディレクティブはリダイレクト時のLocationヘッダに埋め込むサーバ名を制御します。次のようにserver_name_in_redirectディレクティブを"on"にすると、リダイレクトするときにserver_nameディレクティブで設定したプライマリサーバ名が使われるようになります。

server_name_in_redirect on;

次のように"off"に設定すると、リクエストのHostヘッダ フィールドで指定されたホスト名が使われます。しかし、Hostヘッダ フィールドが無いときにはサーバのIPアドレスが使われることに注意しましょう。

server_name_in_redirect off;

プライマリサーバ名が正規表現や"*"を使っているときには"off"に設定設定する必要があるでしょう。むしろこの場合は正規なプライマリサーバ名を設定した方がよいとは思いますが。

なお、デフォルト値は"on"です。

デフォルトサーバ

複数のバーチャルサーバがあるときには、リクエストのHost:ヘッダ フィールドのホスト名がserver_nameディレクティブのサーバ名に一致するserverディレクティブのバーチャルサーバが適応されます。しかし、一致しない場合にはデフォルトサーバとして選ばれたバーチャルサーバが適応されます。

デフォルトサーバはIPアドレスとポート番号の条件が一致したlistenディレクティブを持つserverディレクティブの中で次のものが選ばれます。

  • 一致したlistenディレクティブの中でdefault_serverオプションを持つ
  • 設定ファイル内で最初に一致したlistenディレクティブを持つ

listenディレクティブにdefault_serverパラメータを付けると、そのserverディレクティブがデフォルトサーバになります。

listen *:80 default_server;

default_serverパラメータがない場合には、最初にIPアドレスとポート番号の条件に一致したlistenディレクティブを持つserverディレクティブがデフォルトサーバになります。本記事の最初に述べたように複数のバーチャルサーバ毎の設定ファイルがある場合には、読み込まれる順番は不定であるため、どのバーチャルサーバの設定が最初に読み込まれるかはわかりません。そのため、明示的にdefault_serverパラメータを付けた方がよいでしょう。

以上のようにlistenディレクティブとserver_nameディレクティブにより、どのバーチャルサーバが適応されるかが決まります。

ドキュメントルート - root

root   /usr/share/nginx/html;

rootディレクティブにはドキュメントルートのディレクトリを設定します。httpコンテキスト、serverコンテキスト、locationコンテキスト、location内のifコンテキストに記述できます。上記の例では/usr/share/nginx/htmlがドキュメントルートとなります。

大抵はserverコンテキストあるいは次のように"/"のlocationコンテキストに標準のドキュメントルートを設定して、必要に応じて個別のパスのlocationコンテキストに個別にドキュメントルートを設定することになります。

location / {
    root   /usr/share/nginx/html;
}

今回はここまでです。locationについては書く内容が多くなるので、次回に続きます。

株式会社ハートビーツの技術情報やイベント情報などをお届けする公式ブログです。



ハートビーツをフォロー

  • Twitter:HEARTBEATS
  • Facebook:HEARTBEATS
  • HATENA:HEARTBEATS
  • RSS:HEARTBEATS

殿堂入り記事