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ディレクティブの基本的な使い方の一部を書いた。 追加があればアップデートしていくかもしれない