Panda Noir

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

Nginxでlocationの書き方はとりあえずコレにしておけ

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

  • ネストするとおかしくなる
  • 同じ階層にあるうち一つしか適用されない
  • 同じ階層のlocationディレクティブの演算子をすべてチェックしないと、どれが適用されるかわからない

このように、Nginx の locationディレクティブは直感的ではなく、クセのある動作をします。

今回はとてもカンタンで、ファイル分割管理が楽になるやり方をご紹介します。

locationの基礎事項

まずlocationの基礎知識ですが、locationは並列して書かれていた場合、どれか一つのみ適用されます。どれが適用されるかは演算子によります。

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

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

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

ネストを活用すれば読みやすい設定がかける!

locationのネストはしてはいけないという記事がありますが、locationはネストしていいですドキュメントにキッパリ書いてあります。今回はこのlocationのネストを活用していきます。

ネストによる引き継ぎについて

ネストさせてもいい、と書きましたが、これには注意点があります。たとえば以下のケースです。

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

このときconfigure Aは適用されないケースがあります。引き継ぎされる場合もありますが、されないディレクティブもあるようです。ドキュメントに明示されていなかったので、具体的な仕様が分かりません。深く検証した記事が存在しないので、configure Aには何も書かないのが無難でしょう。

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

さて、今回のキモとなるベストプラクティスです。

さきほど優先順位の話をしましたが、優先順位なんて忘れてください。全く必要ありません。なぜなら、優先順位を活用しようとするとファイルを分割したときに困るからです。同じ階層で異なる優先順位の演算子を使ってしまうと、複数ファイルに分けたときに全ての演算子を覚えて、どれが適用されるのか調べるのはとても大変です。

ならどうすればいいのでしょうか?正解は「同じ層は同じ演算子のみ」とすればいいのです。そうすればどれが適用されるのか迷わなくなります。

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

実例

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

location /hoge {
  # /hoge以下の設定を書く
  location = /hoge/fuga {
    # 完全一致のケース
    #configure B
  }
  location ~ ^/hoge/.*\.php$ {
    # 正規表現のケース
    # configure C
  }
  location /hoge {
    # 上のケースに当てはまらなかった場合
    # configure D
  }
}
location /fuga {
  # /fuga以下の設定を書く
  location ~ ^/fuga/.*\.php$ {
  }
  location /fuga {
  }
}
location /{
  # それ以外の設定を書く
  location ~ \.php$ {
    # configure B
  }
  location / {
    # configure C
  }
}

このように書くと、演算子の優先度が同じなので、ディレクトリごとでファイルを分割できるようになります。

注意点

この方法はネストを使っているので、パフォーマンスはどうしても落ちてしまいます。大規模サービスを作ると影響が出てくるかもしれません。

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

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