Panda Noir

JavaScript の限界を究めるブログでした。最近は幅広めに書いてます。

Nginxでlocationの書き方がわからない時に読む記事

「Nginxのlocationの書き方がわからない!」そう思ったことはありませんか?

  • ネストするとおかしくなる
  • 同じ階層にあるうち一つしか適用されない

など 、locationディレクティブは直感的でない、クセがある動作をします。

今回、Nginx実践入門とNginxドキュメントを読んで理解が深まったので、自分なりにベストプラクティスをまとめてみました。

locationの基礎事項

locationは並列して書かれていた場合、どれか一つのみ適用されます

どれが適用されるかはlocationの書き方によります。

「=、^~、~、~*、なし」の順に適用されます。

=完全一致
^~前方一致
~case-sensitive*1な正規表現
~case-insensitive*2な正規表現
なし前方一致

^~と「演算子なし」は正規表現に対する優先順位が異なります。

ネストはしてもいい

まずlocationのネストはしてもいいです。ドキュメントにキッパリ書いてあります

バリバリ使いましょう。

個人的ベストプラクティス

さて優先順位の話をしましたが、優先順位なんて忘れてください。全く必要ありません。

優先順位を覚えていないといけないのは、同じ層に異なる演算子があるためです。同じ層を複数ファイルに分けている場合、すべての演算子を記憶するのは大変です。ならどうすればいいのでしょうか?

正解は「同じ層は同じ演算子のみ」にすればいいのです。

まず、第一層は「演算子なし」のlocationのみで書きます。ネストさせて第二層は正規表現を使って書いていきます。

注意するのは、ネストさせても受け継ぎがうまくいかないケースがあることです。

例えば次のようなケースです。

location /hoge {
  # configure A
  location ~ ^/hoge/.*\.php {
    # configure B
  }
  location ~ .* {
    # configure C
  }
}

このときconfigure Aは適用されないことがあります。ドキュメント読んでもそこについては明示されていなかったので、どういう仕様かは分かりません。しかし、configure Aは書かないのが無難でしょう。

個人的ベストプラクティス

まず、ディレクトリ名で分けます。 中には「完全一致」「正規表現」「その他のケース」を書きます。

location /hoge {
  #ここには書かない
  location = /hoge/fuga {
    #configure B
  }
  location ~ ^/hoge/.*\.php$ {
    # configure C
  }
  location /hoge {
    # 上のケースに当てはまらなかった場合
    # configure D
  }
}
location /fuga {
  #ここには書かない
  location ~ ^/fuga/.*\.php$ {
  }
  location /fuga {
  }
}
location /{
  #ここには書かない
  location ~ \.php$ {
    # configure B
  }
  location / {
    # configure C
  }
}

このように書くことで他の設定との競合を防ぎやすくなります。ただし、必ずネストする構造になるのでパフォーマンスは落ちます。

*1:大文字と小文字を区別する

*2:大文字と小文字を区別しない