dshimizu/blog

アルファ版

今更Nginxのlocationディレクティブについてのメモ

Nginxのlocationディレクティブを頻繁にいじることがなく、いざ設定しようとするとゴタゴタしてしまうので基本的な書き方の一部をメモがてら書いておく。

静的コンテンツをキャッシュさせたい

特定のPATHのものをキャッシュさせたい場合、例えば/static/に静的コンテンツがあり、それらをキャッシュさせたい場合は下記のようになる。

server {
    :
    location /static/ {
        root           /path/to/public;
        autoindex      on;
        expires        1d;
        add_header Cache-Control "private max-age=86400";
    }
    :
}

静的コンテンツをキャッシュさせたい(正規表現)

/static/の中の画像やCSS、JSなどを正規表現で指定してキャッシュさせたい場合は下記のようになる。

~正規表現の始まりを表し、^で行頭を、()の中が正規表現を指す。最初の.*で任意の文字の繰り返しを表し、.(html?|jpe?g|gif|pdf|png|css|js|ico|swf|inc)で各ファイルの拡張子を表す。最後の $ は行の終わりを意味する。

server {
    :
    location ~ ^/static/(.*\.(html?|jpe?g|gif|pdf|png|css|js|ico|swf|inc))$  {
        root           /path/to/public;
        autoindex on;
        expires 30d;
        add_header Cache-Control "private max-age=86400";
    }
    :
}

etagを使う場合、etagの値の生成には一般的に最終更新日時のハッシュが用いられるため、複数台のサーバがある場合は各サーバの画像ファイルの更新日時も統一しておく必要がある。

ファイルの存在をチェックする(try_files)

try_files自体はtry_files file_path ... uri;のような構文で記載して、順番にファイルの存在をチェックして、最初に見つかったファイルでリクエストを処理する。

例えば下記のような記載で、example.com/images/hogehoge.pngというリクエストがあった場合に、$uri/images/hogehoge.pngとなってファイルの存在チェックをし、それが存在しなければ/images/default.gifにリクエストされる。 $uri/のように最後に/をつけると、ディレクトリと判定してくれる。

server {
    :
    server_name   example.com;
    root          /path/to/public;

    location /images/ {
        try_files $uri /images/default.gif;
    }
    :
}

プロキシさせる(proxy_pass)

/hogehogeへのリクエストを特定のサーバで処理させたい場合は下記のようにする。

server {
    root /var/www/example.com;
    location /hogehoge {
        proxy_pass  http://server01.example.com:3000;
    }
}

複数台のサーバに分散させたい場合は下記のようにupstreamディレクティブを使って分散対象のサーバを定義する。

upstream server.example.com {
    server server01.example.com:3000;
    server server02.example.com:3000;
}

server {
    root /var/www/example.com;
    location / {
        proxy_pass  http://server.example.com;
    }
}

fastCGIへリクエストを投げる

例えばphp-fpm等のFastCGIのプロセスにリクエストを投げたい場合は下記のようにする。下記の例ではFastCGIプロセスは8080で応答しているモノとする。 fastcgi_param の項目を変更したいものがある場合は、 include fastcgi_params; の後に記述する


server {
    root /var/www/example.com;
    location / {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        if (!-f $document_root$fastcgi_script_name) {
            return 404;
        }
        fastcgi_pass  server01.example.com:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME public/$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}

複数台のサーバのFastCGIに分散させたい場合はproxy_passの時とほぼ同様でupstreamディレクティブを使って分散対象のサーバを定義する。

upstream server.example.com {
    server server01.example.com:9000;
    server server02.example.com:9000;
}

server {
    root /var/www/example.com;
    location / {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        if (!-f $document_root$fastcgi_script_name) {
            return 404;
        }
        fastcgi_pass  server.example.com;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME public/$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}

特定のパスのみサーバー1号機にリクエストを投げたい、といった場合は以下のようなやり方になると思う。

upstream server.example.com {
    server server01.example.com:9000;
    server server02.example.com:9000;
}

server {
  location ~ ^/froo {
    try_files $uri $uri/ @s1;
  }

  location / {
    try_files $uri /index.php?$query_string;
  }

  location @s1 {
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME public/index.php;
    fastcgi_pass server02.example.com:9000;
  }

  location = /index.php {
    include fastcgi_params;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME public/$fastcgi_script_name;
    fastcgi_pass server.example.com;

    if 
  }
}

こちら によると if で分岐する方法が良いらしい、と書かれている。

upstream server.example.com {
    server server01.example.com:9000;
    server server02.example.com:9000;
}

server {
  location / {
    try_files $uri /index.php?$query_string;
  }

  location = /index.php {
    include fastcgi_params;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME public/$fastcgi_script_name;
    fastcgi_pass server.example.com;

    if ($request_uri ~ "^/foo$") {
        fastcgi_pass server02.example.com:9000;
    }

  }
}

まとめ

Nginxのlocationディレクティブの基本的な使い方の一部を書いた。 追加があればアップデートしていくかもしれない

参考