nginxの設定を正しく理解したい

Blog Single

こんにちは、枕詞が枯渇ぎみの高橋です。
先日、業務でnginxの設定を変更する機会があったのですが、意図した挙動にならず苦戦しました。
そんなわけで今回はnginxの設定について調べたことを書いていきたいと思います。

location

locationは、URIのパス毎の設定を可能にします。

記法は次のようになります。

location [プレフィックス] URIパス {
    [設定]
}

プレフィックスにはURIパスをどのように評価するかを指定します。

プレフィックス 説明
= 完全一致。パスが等しければ正規表現の条件は評価しない
^~ 前方一致。一致したら、正規表現の条件を評価しない
~ 大文字、小文字を区別する正規表現
~* 大文字、小文字を区別しない正規表現
なし 前方一致

これらはそれぞれ以下のように使われます。

# /contact/index.htmlに完全一致する場合
# 以降の条件は評価されない
location = /contact/index.html {
    [設定1]
}

# /photoで始まる場合
# 以降の条件は評価されない
location ^~ /photo/ {
    [設定2]
}

# /tag/Godで始まる場合
location ~ ^\/tag\/God.*$ {
    [設定3]
}

# .jpeg(.JPEG)、.jpg(.JPG)、.png(.PNG)の場合
location ~* \.(jpe?g|png)$ {
    [設定4]
}

# /blogで始まる場合
# ただし、正規表現や文字列が長いものが優先
location /blog/ {
    [設定5]
}

index

indexはリクエストのURIがディレクトリになっている場合に使われるファイル名を設定します。
内部リダイレクトは302などのレスポンスコードを指定するものとは違い、Webサーバー内部でURIパスの書き換えを行うことを指します。
内部リダイレクト後はリダイレクト先のパスに対して最初からlocationの評価が行われます。

# リクエストURIパスが'/blog/'から始まる時に、default.htmlが存在すればdefault.htmlに内部リダイレクト
# default.htmlが存在せず、default.phpが存在すればdefault.phpに内部リダイレクト
location /blog/ {
    index default.html default.php;
}

# 内部リダイレクトはここの設定が適応される
location = /blog/default.html {
    [設定]
}

rewrite

rewriteはリクエストのURIを書き換えて、リダイレクトさせることができます。

記法は次のようになります。

rewrite 正規表現 変換後URI [フラグ];

フラグを指定することによって動作を制御することができます。

フラグ 説明
last 書き換えられたURIに対して最初からlocationの評価をやり直す
break URIを書き換え、locationの評価を終了する
permanent 恒久的なリダイレクト(301)
redirect 一時的なリダイレクト(302)

これらはそれぞれ以下のように使われます。

# '/blog/'から始まるリクエストURIパスを'/information/index.html'に書き換える
# locationの評価がやり直され、info設定が適応される
location /blog/ {
    [blog設定]
    rewrite ^\/blog\/.*$ /information/index.html last;
}

location /information/ {
    [info設定]
}


# '/blog/'から始まるリクエストURIパスを'/information/index.html'に書き換える
# locationの評価が終了して、blog設定が適応される
location /blog/ {
    [blog設定]
    rewrite ^\/blog\/.*$ /information/index.html break;
}

location /information/ {
    [info設定]
}


# '/old/'から始まるリクエストURIパスを'/new/'から始まるURIパスに301リダイレクトさせる
location /old/ {
    rewrite ^\/old\/(.*)$ /new/$1 permanent;
}


# '/information'から始まるリクエストURIパスを'/event/index.html'に302リダイレクトさせる
location /information/ {
    rewrite ^\/information\/.*$ /event/index.html redirect;
}

try_files

try_filesは指定したファイルやディレクトリが存在すれば対応したファイルを返し、存在しなかったら最後に記述したパスに内部リダイレクトするものでアプリケーションとの連携に使われることが多いようです。

以下は、Laravel5.5を使用する際に推奨される設定です。
$uri: パラメータを除いたリクエストURI
$query_string: 全てのGETリクエストを結合したパラメータ

# まず、URIパスにファイルが存在するかチェック
# ファイルが存在しない場合、URIパスにディレクトリが存在するかチェック
# ファイル、ディレクトリが存在しない場合、`/index.php`に内部リダイレクトする
location / {
    try_files $uri $uri/ /index.php?$query_string;
}

まとめ

今回、nginxの設定について調べたことで、業務で苦戦した原因がrewriteのフラグによる動作の認識違いであったことがわかりました。
また、nginxに限らずWebサーバー周りの作業では、安易に試してみるといったことができない場面があると思います。
そんな環境でも作業に自信を持つために正確な知識を得る必要があると強く感じました。

参考

心無い冗談を愛するエンジニア。音楽とサッカーが好きです。

Other Posts: