【入門】Nginx location の基礎知識と書き方・設定例

はい、承知いたしました。Nginxのlocationディレクティブに関する基礎知識、書き方、設定例を詳細に解説した約5000語の記事を作成します。


【入門】Nginx location の基礎知識と書き方・設定例

はじめに:Nginxとlocationディレクティブの重要性

ウェブサーバーとして世界中で広く使われているNginxは、高速かつ軽量なパフォーマンスと高い拡張性で知られています。静的ファイルの配信から、リバースプロキシ、ロードバランシング、キャッシュ、SSLターミネーションまで、多岐にわたる役割をこなすことができます。

Nginxが受信したクライアントからのHTTPリクエストをどのように処理するかを決定する上で、最も中心的かつ重要な役割を果たすのが、今回詳細に解説するlocationディレクティブです。

クライアントがウェブサイトにアクセスする際、通常はURL(Uniform Resource Locator)を入力します。例えば https://www.example.com/path/to/resource.html のようなURLです。NginxはこのURLに含まれるURI(Uniform Resource Identifier)、つまり location ディレクティブでは主にURLのホスト名の後ろの部分(/path/to/resource.html)を見て、そのリクエストをどのハンドラーに引き渡すか、あるいはどのように応答するかを決定します。

locationディレクティブは、URIと照合するための「パターン」を定義し、そのパターンにマッチしたリクエストに対して適用される一連の設定(静的ファイルの場所、プロキシの宛先、キャッシュ設定、アクセス制御など)を記述するためのブロックです。

もしlocationディレクティブを正しく理解していなければ、以下のような問題に直面する可能性があります。

  • 意図したファイルが配信されない(404 Not Foundエラーなど)
  • アプリケーションサーバーへのリクエストが正しく転送されない
  • セキュリティ設定(特定のIPからのアクセス制限など)が正しく機能しない
  • パフォーマンスチューニング(キャッシュ設定など)が適用されない
  • 複雑なルーティングやリダイレクトが実現できない

逆に言えば、locationディレクティブをマスターすることは、Nginxの設定において最も基礎的かつ強力なスキルとなります。本記事では、Nginx初心者の方でも理解できるよう、locationディレクティブの基本から、様々なマッチング方法、重要な内部ディレクティブ、そして具体的な設定例までを詳細かつ網羅的に解説します。

さあ、Nginxの強力なルーティング機能の中核であるlocationディレクティブの世界へ足を踏み入れましょう。

第1章: locationディレクティブとは何か? その役割

locationディレクティブは、Nginxの設定ファイル(通常 nginx.conf やそのincludeファイル)内のserverブロック内に記述されます。一つのserverブロックは通常、特定の仮想ホスト(ドメイン名やIPアドレス、ポート番号の組み合わせ)に対応します。

クライアントからNginxサーバーへのリクエストがあると、Nginxはまずそのリクエストのホスト名とポート番号を見て、対応するserverブロックを選択します。次に、選択されたserverブロック内で、リクエストURIがどのlocationディレクティブのパターンにマッチするかを評価します。そして、最も適切だと判断されたlocationブロック内の設定を適用してリクエストを処理します。

locationディレクティブの主な役割は以下の通りです。

  1. URIベースのルーティング: 特定のURIパス(例: /images/, /api/v1/, /admin/)に来たリクエストを識別する。
  2. ハンドリングの決定: 識別されたリクエストに対して、どのように応答するか(静的ファイル配信、プロキシ、リダイレクト、エラー応答など)を決定する。
  3. 設定の適用: 特定のパスに対して、rootaliasによるドキュメントルートの指定、indexファイルの指定、proxy_passによるバックエンドサーバーへの転送、キャッシュ設定、アクセス制御、ヘッダー操作などの詳細な設定を適用する。

例えば、ウェブサイトの構造が以下のようになっているとします。

  • / (トップページ): アプリケーションサーバーが生成する動的なコンテンツ
  • /static/: CSS、JavaScript、画像などの静的ファイル
  • /images/: 特に画像ファイル
  • /api/: バックエンドAPIへのリクエスト
  • /download/: 大容量のダウンロードファイル

このような場合、それぞれのパスに対して異なる処理を行いたいと考えられます。

  • //api/ に来たリクエストはアプリケーションサーバー(例えばNode.js, Python/Django, Ruby/Railsなど)に転送したい。
  • /static//images/ に来たリクエストはNginx自身がディスク上のファイルとして高速に配信したい。
  • /download/ に来たリクエストには特別な速度制限をかけたい。

これらの要件を実現するために、それぞれのパスに対応するlocationブロックを定義し、それぞれのブロック内に必要な設定(proxy_passrootlimit_rateなど)を記述するのです。

locationディレクティブは、Nginx設定の柔軟性と表現力を支える根幹であり、これを使いこなすことがNginxを効果的に活用するための第一歩となります。

第2章: locationディレクティブの基本構文と構造

locationディレクティブの基本的な構文は以下の通りです。

nginx
location [modifier] pattern {
# このブロック内で設定されるディレクティブは、
# パターンにマッチしたリクエストに適用される
...
}

  • location: ディレクティブの名前です。
  • [modifier]: マッチング方法を指定する「修飾子(modifier)」です。この修飾子の有無や種類によって、patternとの照合ルールや、複数のlocationブロックが存在する場合の優先順位が変化します。修飾子は省略可能です。
  • pattern: リクエストURIと比較される文字列または正規表現です。
  • { ... }: このブロック内に、パターンにマッチしたリクエストに対して適用するNginxの設定ディレクティブを記述します。

serverブロック内には、複数のlocationブロックを記述することができます。Nginxはリクエストを受け取ると、これらのlocationブロックを特定のルールに従って評価し、最初にマッチしたブロック(ただし、正規表現マッチの場合は少しルールが異なります。詳細は後述します)の設定を適用します。

例:

“`nginx
server {
listen 80;
server_name example.com;

# ルートパス('/')にマッチするlocationブロック
location / {
    # ここにルートパス用の設定を記述
    proxy_pass http://localhost:3000; # アプリケーションサーバーへ転送
}

# '/static/'で始まるパスにマッチするlocationブロック
location /static/ {
    # ここに静的ファイル配信用の設定を記述
    root /var/www/example.com/static; # 静的ファイルの場所を指定
    expires 30d; # クライアント側でのキャッシュ期間を設定
}

# '/api/'で始まるパスにマッチするlocationブロック
location /api/ {
    # ここにAPIリクエスト用の設定を記述
    proxy_pass http://localhost:8000; # APIサーバーへ転送
    limit_req zone=api burst=5 nodelay; # リクエストレート制限
}

# 特定のファイル拡張子にマッチするlocationブロック (正規表現を使用)
location ~* \.(jpg|jpeg|gif|png|css|js|ico)$ {
    # ここに画像やCSS/JSファイル用の設定を記述
    root /var/www/example.com/public;
    expires max; # キャッシュ期間を最大に設定
    log_not_found off; # ファイルが見つからない場合でもエラーログを出力しない
}

# 別の特定のパスに完全に一致する場合のlocationブロック
location = /favicon.ico {
    # favicon.ico のみにマッチ
    root /var/www/example.com/public;
    expires 365d;
}

}
“`

上記の例のように、一つのserverブロック内に複数のlocationブロックを定義することで、リクエストURIに応じてきめ細やかな処理を設定することができます。

第3章: locationディレクティブの修飾子(Modifier)

locationディレクティブのpatternの前につける修飾子は、リクエストURIとパターンのマッチング方法、そして複数のlocationブロックが存在する場合の評価順序に大きく影響します。主要な修飾子は以下の通りです。

  1. 修飾子なし (Prefix Match)

    • 構文: location pattern { ... }
    • 例: location /images/ { ... }
    • これは最も一般的な形式です。patternで指定された文字列が、リクエストURIの先頭部分(プレフィックス)と一致する場合にマッチします。
    • 例: location /documents/ { ... } という設定がある場合、以下のURIにマッチします。
      • /documents/report.pdf
      • /documents/
      • /documents/folder/image.jpg
    • pattern/ の場合は、すべてのリクエストURIのプレフィックスとマッチするため、特別な意味を持ちます。通常、他のどのlocationブロックにもマッチしなかったリクエストを処理するための「キャッチオール」的な役割を果たします。
    • 注意点: プレフィックスマッチは、「最も一致したプレフィックス」が選ばれるわけではありません。評価順序のルールに基づいてマッチする候補がいくつか挙がった後、最終的に優先順位の高いものが選ばれます(詳細は後述の「評価順序」の章で解説します)。ただし、複数のプレフィックスマッチ候補がある場合、最も長く一致するプレフィックスを持つものが優先されます。
  2. = (Exact Match)

    • 構文: location = pattern { ... }
    • 例: location = /login { ... }
    • リクエストURI全体がpatternで指定された文字列と完全に一致する場合にのみマッチします。
    • 例: location = /login { ... }/login にはマッチしますが、/login//login?user=test にはマッチしません(クエリ文字列はマッチングの対象外です)。
    • この修飾子を持つlocationブロックは、他のどのタイプのlocationブロックよりも最優先で評価されます。
    • 特定のパス(例: /favicon.ico, /)に対して、高速に処理を決定したい場合に使用すると効果的です。
  3. ~ (Case-sensitive Regular Expression Match)

    • 構文: location ~ pattern { ... }
    • 例: location ~ \.(gif|jpg|png)$ { ... }
    • リクエストURIがpatternで指定された正規表現に大文字・小文字を区別してマッチする場合に適用されます。
    • 正規表現を使用するため、非常に柔軟なマッチングが可能です。
    • 例: location ~ \.(gif|jpg|png)$ { ... }/images/photo.png, /data/logo.gif にはマッチしますが、/documents/report.PNG/scripts/app.js にはマッチしません。
  4. ~* (Case-insensitive Regular Expression Match)

    • 構文: location ~* pattern { ... }
    • 例: location ~* \.(gif|jpg|png)$ { ... }
    • リクエストURIがpatternで指定された正規表現に大文字・小文字を区別せずにマッチする場合に適用されます。
    • 例: location ~* \.(gif|jpg|png)$ { ... }/images/photo.png, /data/logo.gif, /documents/report.PNG のすべてにマッチします。
  5. ^~ (Preferential Prefix Match)

    • 構文: location ^~ pattern { ... }
    • 例: location ^~ /static/ { ... }
    • これはプレフィックスマッチの一種ですが、特別な優先順位を持ちます。もしリクエストURIが^~付きのlocationブロックのpattern最長で一致した場合、Nginxは正規表現マッチの評価をスキップし、この^~付きブロックの設定を即座に適用します。
    • 特定のプレフィックス(例: /static/, /uploads/)配下のファイルに対して、正規表現によるマッチング(例えばファイル拡張子によるマッチング)よりも優先的にプレフィックスによる静的ファイル配信を設定したい場合などに有効です。正規表現マッチはプレフィックスマッチよりも評価コストが高い傾向があるため、パフォーマンスの観点からも有利になることがあります。
  6. ! (Negative Match – 非公式/注意)

    • Nginxの公式ドキュメントには!!~!~*といった否定の修飾子は基本的には存在しません(少なくとも主要なバージョンでは)。一部のサードパーティモジュールが提供している可能性はありますが、標準機能としては利用できないと考えてください。
    • URIが特定のパターンにマッチしない場合の設定を行いたい場合は、肯定の正規表現マッチ(~~*)やifディレクティブ(非推奨とされることが多いですが)を組み合わせて実現するか、マッチさせたいパターンとマッチさせたくないパターンを分けて複数のlocationブロックで定義するなどの工夫が必要です。例えば、「/static/以下だが、特定のファイル拡張子(.phpなど)は除く」といった場合は、/static/のプレフィックスマッチブロックでデフォルト処理を書きつつ、より優先順位の高い正規表現ブロックで除外したいパターンに対する処理(例えば404エラーを返す)を記述する、といったアプローチが考えられます。

修飾子のまとめ:

修飾子 マッチング方法 優先順位に関する特徴
= 完全一致 最高優先。一致した場合、他のブロックは評価されない。
^~ プレフィックス一致 (優先) プレフィックスマッチの中で最長一致。一致した場合、正規表現マッチの評価をスキップする。
~ 正規表現一致 (大文字小文字区別) ^~付きプレフィックスマッチよりも優先順位は低いが、修飾子なしプレフィックスマッチよりは高い。
~* 正規表現一致 (大文字小文字無視) ^~付きプレフィックスマッチよりも優先順位は低いが、修飾子なしプレフィックスマッチよりは高い。
なし プレフィックス一致 (通常) プレフィックスマッチの中で最長一致が候補となる。正規表現マッチよりも優先順位が低い。

この優先順位のルールを理解することが、複数のlocationブロックがどのように機能するかを理解する上で最も重要です。

第4章: 複数のlocationブロックがある場合の評価順序 (超重要!)

NginxがリクエストURIに対してどのlocationブロックの設定を適用するかを決定するプロセスは、初心者にとって最も混乱しやすい部分です。しかし、このルールさえ押さえれば、複雑なNginx設定も読み解けるようになります。

Nginxは、リクエストURIに対して、serverブロック内に定義されたlocationブロックを以下のステップで評価します。

  1. Step 1: = (Exact Match) の評価

    • Nginxはまず、すべての=付きlocationブロックを確認し、リクエストURIと完全に一致するパターンがあるかを調べます。
    • もし完全に一致する=付きブロックが見つかった場合、Nginxは即座にそのブロックの設定を適用し、他のすべてのlocationブロックの評価を停止します。これが最も優先されます。
    • 一致する=付きブロックが見つからなかった場合、次のStep 2に進みます。
  2. Step 2: ^~ (Preferential Prefix Match) の評価

    • 次に、Nginxはすべての^~付きlocationブロックを確認し、リクエストURIのプレフィックスとして一致するパターンを探します。
    • 複数の^~付きブロックが一致する可能性がある場合、NginxはリクエストURIと最も長く一致するプレフィックスを持つブロックを選択します。
    • もし最長一致する^~付きブロックが見つかった場合、Nginxは直ちにそのブロックの設定を適用し、正規表現マッチ (Step 3) の評価をスキップします。修飾子なしのプレフィックスマッチ (Step 4) の評価も行いません。
    • 一致する^~付きブロックが見つからなかった場合、次のStep 3に進みます。
  3. Step 3: ~ および ~* (Regular Expression Match) の評価

    • Step 1とStep 2でマッチが見つからなかった場合、Nginxはすべての~ (大文字小文字区別) および ~* (大文字小文字無視) 付きlocationブロックを確認し、リクエストURIが正規表現パターンにマッチするかを調べます。
    • 正規表現マッチは、設定ファイルに記述されている順番に評価されます。
    • もし正規表現に最初にマッチしたブロックが見つかった場合、Nginxは即座にそのブロックの設定を適用し、以降の正規表現ブロックや残りのプレフィックスマッチ (Step 4) の評価を停止します。
    • どの正規表現パターンにもマッチしなかった場合、次のStep 4に進みます。
  4. Step 4: 修飾子なし (Prefix Match) の評価

    • Step 1, 2, 3のどれでもマッチしなかった場合、Nginxはすべての修飾子なしlocationブロックを確認し、リクエストURIのプレフィックスとして一致するパターンを探します。
    • 複数の修飾子なしブロックが一致する可能性がある場合、NginxはリクエストURIと最も長く一致するプレフィックスを持つブロックを選択します。
    • Nginxは最終的に、このステップで見つかった最長一致のプレフィックスマッチブロックの設定を適用します。
    • 通常、location / { ... } というブロックはすべてのURIにプレフィックスとしてマッチするため、他のどのブロックにもマッチしなかった場合の最後の砦 (fallback) として機能します。

評価順序のまとめ (優先度の高い順)

  1. = (Exact match)
  2. ^~ (Preferential prefix match) での最長一致
  3. ~ または ~* (Regular expression match) – 設定ファイルに記述されている最初のマッチ
  4. 修飾子なし (Prefix match) での最長一致

重要なポイント:

  • = マッチは最速で決定され、他のすべてをスキップします。
  • ^~ マッチは、正規表現マッチよりもプレフィックスマッチを優先させたい場合に使います。^~が最長一致した場合、正規表現は評価されません。
  • 正規表現マッチ (~, ~*) は、設定ファイルに書かれている順序が重要です。最初にマッチした正規表現ブロックが採用されます。
  • 修飾子なしのプレフィックスマッチは、最も優先度が低く、正規表現マッチがどれも一致しなかった場合に評価されます。複数のプレフィックスマッチがある場合は、最長一致が選ばれます。
  • location / { ... } は通常、修飾子なしのプレフィックスマッチとして定義され、他のすべてのlocationブロックにマッチしなかったリクエストを処理する役割を果たします。

例で理解する評価順序

以下のserverブロック設定があるとします。

“`nginx
server {
listen 80;
server_name example.com;

location = /login {
    # Rule 1: Exact match for /login
    return 200 "Exact /login";
}

location /static/images/ {
    # Rule 2: Prefix match for /static/images/
    return 200 "Prefix /static/images/";
}

location ^~ /static/ {
    # Rule 3: Preferential prefix match for /static/
    return 200 "Preferential prefix /static/";
}

location ~* \.(png|jpg|jpeg)$ {
    # Rule 4: Case-insensitive regex match for images
    return 200 "Regex image file";
}

location / {
    # Rule 5: Catch-all prefix match
    return 200 "Catch-all /";
}

}
“`

さて、以下のリクエストURIが来た場合、どのlocationブロックが選ばれるでしょうか?

  1. URI: /login

    • Step 1 (=): location = /login に完全に一致します。
    • 結果: Rule 1 (Exact /login) が適用されます。他のブロックは評価されません。
  2. URI: /static/css/style.css

    • Step 1 (=): どの=ブロックにも一致しません。
    • Step 2 (^~): location ^~ /static/ にプレフィックス一致します。これが唯一の^~マッチなので、最長一致です。
    • 結果: Rule 3 (Preferential prefix /static/) が適用されます。正規表現マッチはスキップされます。
  3. URI: /static/images/photo.png

    • Step 1 (=): どの=ブロックにも一致しません。
    • Step 2 (^~): location ^~ /static/ にプレフィックス一致します。これが唯一の^~マッチなので、最長一致です。
    • 結果: Rule 3 (Preferential prefix /static/) が適用されます。これは多くの初心者にとって直感に反するかもしれません。「/static/images/の方が長いし、正規表現もマッチするのに?」と思うかもしれませんが、^~ /static/ がマッチした時点で正規表現の評価はスキップされるのです。/static/images/photo.png/static/ のプレフィックスを含んでいるため、^~ /static/ がStep 2で最長一致として選ばれます。

    • もし location ^~ /static/ がなければ:

      • Step 1 (=): マッチなし。
      • Step 2 (^~): マッチなし。
      • Step 3 (~, ~*): location ~* \.(png|jpg|jpeg)$ に正規表現一致します。
      • 結果 (without Rule 3): Rule 4 (Regex image file) が適用されます。
      • このように、^~ の有無が評価結果に大きく影響します。
  4. URI: /documents/report.pdf

    • Step 1 (=): マッチなし。
    • Step 2 (^~): マッチなし。
    • Step 3 (~, ~*): どの正規表現パターンにもマッチしません(.pdf はリストにない)。
    • Step 4 (なし): location / にプレフィックス一致します。これが唯一の修飾子なしブロックです。
    • 結果: Rule 5 (Catch-all /) が適用されます。
  5. URI: /some/other/path

    • Step 1 (=): マッチなし。
    • Step 2 (^~): マッチなし。
    • Step 3 (~, ~*): マッチなし。
    • Step 4 (なし): location / にプレフィックス一致します。
    • 結果: Rule 5 (Catch-all /) が適用されます。
  6. URI: /static/some/image.GIF

    • Step 1 (=): マッチなし。
    • Step 2 (^~): location ^~ /static/ にプレフィックス一致します。最長一致。
    • 結果: Rule 3 (Preferential prefix /static/) が適用されます。正規表現マッチはスキップされます。

この評価順序と、特に^~が正規表現マッチをスキップさせる点、そして正規表現マッチが記述順に評価される点をしっかりと理解することが、意図した通りにNginxを設定するための鍵となります。

第5章: locationブロック内でよく使われるディレクティブ

locationブロックの中には、そのパスにマッチしたリクエストに対して具体的な処理内容や設定を記述するための様々なディレクティブを配置します。ここでは、特によく使われる基本的なディレクティブをいくつか紹介します。

  1. root ディレクティブ

    • 構文: root path;
    • 例: root /var/www/html;
    • 静的ファイルを配信する際に、リクエストURIに対応するファイルを探すためのファイルシステム上のルートパスを指定します。
    • Nginxは、rootで指定されたパスに、locationパターンにマッチしたリクエストURIの残りの部分を結合して、探すべきファイルのフルパスを生成します。
    • 例:
      nginx
      location /static/ {
      root /var/www/mywebsite;
      }

      http://example.com/static/css/style.css というリクエストURIが来た場合、/static/ にマッチし、root ディレクティブが /var/www/mywebsite と指定されています。Nginxは /var/www/mywebsite にリクエストURIの残りの部分である /static/css/style.css を結合して、/var/www/mywebsite/static/css/style.css というファイルを探しに行きます。
    • これは非常に重要なポイントです。rootは指定されたパスにURI全体をくっつけます。
  2. alias ディレクティブ

    • 構文: alias path;
    • 例: alias /path/to/files/;
    • これも静的ファイルを配信する際に使いますが、rootとはファイルの探し方が異なります。aliasは、locationパターンにマッチしたURIのマッチした部分を、aliasで指定されたパスに置き換えて、ファイルシステム上のパスを生成します。
    • 例:
      nginx
      location /static/ {
      alias /var/www/mywebsite/static/;
      }

      http://example.com/static/css/style.css というリクエストURIが来た場合、/static/ にマッチします。alias ディレクティブが /var/www/mywebsite/static/ と指定されています。NginxはリクエストURIのマッチした部分 /static//var/www/mywebsite/static/ に置き換えて、残りの /css/style.css を結合し、/var/www/mywebsite/static/css/style.css というファイルを探しに行きます。結果としてrootを使った場合と同じファイルパスになりますが、考え方が異なります。
    • 重要な違い:
      • root: rootパス + URI全体
      • alias: aliasパス + URIの**マッチしなかった部分**
    • location パターンの末尾に / がある場合、alias で指定するパスも末尾に / をつけるのが一般的で、推奨されています。
    • alias は主に、location パターンがプレフィックスマッチや正規表現マッチの場合に、URIの特定の部分を取り除いたり、別のディレクトリ構造にマッピングしたりするのに便利です。

    • root vs alias 具体例 (詳細)
      以下の設定を考えます。
      “`nginx
      server {
      listen 80;
      server_name example.com;

      location /data/ {
          root /web/files;
          # リクエスト: /data/report.pdf
          # 探すファイル: /web/files/data/report.pdf
      }
      
      location /files/ {
          alias /web/data/;
          # リクエスト: /files/document.txt
          # /files/ が /web/data/ に置き換わる
          # 探すファイル: /web/data/document.txt
      }
      
      location /images { # 末尾にスラッシュなし
           alias /web/images/;
           # リクエスト: /images/logo.png
           # /images が /web/images/ に置き換わる
           # 探すファイル: /web/images/logo.png
      
           # リクエスト: /imagesextra/icon.gif
           # /images にプレフィックス一致する
           # /images が /web/images/ に置き換わる (!! 末尾にスラッシュあり)
           # 探すファイル: /web/images/extra/icon.gif (意図と異なる可能性)
           # このため、aliasを使用するlocationパターンは末尾にスラッシュをつけるのが安全
      }
      
      # 正規表現と alias
      location ~ ^/docs/(\d+)/(.*)$ {
           alias /var/www/documents/$1/$2;
           # リクエスト: /docs/123/chapter/notes.txt
           # $1 -> 123, $2 -> chapter/notes.txt
           # 探すファイル: /var/www/documents/123/chapter/notes.txt
           # alias は正規表現のキャプチャグループをパスに含めることができる
      }
      

      }
      ``aliaslocationパターンでマッチした部分を置き換えるため、特に正規表現や、URIのパス構造をファイルシステム上のパス構造と意図的に変えたい場合に便利です。しかし、末尾のスラッシュの扱いで混乱しやすいため注意が必要です。一般的には、root`の方が直感的でシンプルです。

  3. index ディレクティブ

    • 構文: index file ...;
    • 例: index index.html index.htm;
    • クライアントがディレクトリをURIとしてリクエストした場合(例: /static/ のようにパスの末尾が / で終わる場合)、Nginxはそのディレクトリ内で探すべきデフォルトのファイル名を指定します。
    • 指定されたファイル名リストを順番に探し、最初に見つかったファイルが配信されます。
    • serverブロックやhttpブロックで指定することもできますが、locationブロック内で指定すると、そのパス以下でのみ有効なデフォルトファイルを設定できます。
    • location / { index index.html; } は、http://example.com/ へのリクエストに対して /index.html を探すようになります。
  4. try_files ディレクティブ

    • 構文: try_files file ... uri; または try_files file ... =code;
    • 例:
      • try_files $uri $uri/ /index.html;
      • try_files $uri $uri/index.html =404;
    • これは非常に強力で便利なディレクティブです。指定されたファイルを順番に探し、最初に見つかったものを内部リダイレクト(Nginx内での処理の移行)または外部リダイレクト、あるいは指定されたHTTPステータスコードで返します。
    • $uri: リクエストURIです。
    • $uri/: リクエストURIに対応するディレクトリです。indexディレクティブと組み合わせてデフォルトファイルを探すのに使われます。
    • =code: 指定されたHTTPステータスコード(例: =404)を返します。
    • uri: 最後に指定されたURIは、それまでのファイルが見つからなかった場合のフォールバックとして、内部リダイレクトされます。つまり、Nginxは指定されたURIに対して、最初からlocationマッチングを再度行います。
    • try_filesの一般的な用途:
      • 静的ファイルの存在チェック: try_files $uri $uri/ =404; -> リクエストURI($uri)にファイルが見つかればそれを返し、見つからなければディレクトリ($uri/)として探してindexファイルなどを返し、それも見つからなければ404エラーを返す。
      • SPA (Single Page Application) のルーティング: try_files $uri $uri/ /index.html; -> ファイルまたはディレクトリが見つかればそれを返し、見つからなければすべてのリクエストを /index.html に内部リダイレクトし、クライアント側のルーターに処理を委ねる。
  5. proxy_pass ディレクティブ

    • 構文: proxy_pass url;
    • 例: proxy_pass http://localhost:3000;
    • リクエストを別のサーバー(アプリケーションサーバー、APIサーバーなど)に転送するためのディレクティブです。Nginxがリバースプロキシとして機能する際に使用します。
    • urlには、転送先のサーバーのアドレス(IPアドレスやホスト名)とポート番号を指定します。プロトコルとして http:// または https:// を含める必要があります。
    • proxy_passとURIの扱い方 (重要):
      • proxy_pass url;url の末尾にパスが付いている場合 (例: http://localhost:3000/app/)
        • Nginxは、locationパターンにマッチした部分を取り除いたリクエストURIの残りを、proxy_passで指定されたパスの末尾に付けて転送します。
        • 例: location /api/ { proxy_pass http://localhost:8000/backend/; }
          • リクエストURI: /api/users/123
          • /api/ がマッチした部分。これを削除すると /users/123 が残る。
          • 転送先URI: http://localhost:8000/backend/users/123
      • proxy_pass url;url の末尾にパスが付いていない場合 (例: http://localhost:3000)
        • Nginxは、リクエストURIの全体をそのまま転送先のサーバーに送ります。
        • 例: location /api/ { proxy_pass http://localhost:8000; }
          • リクエストURI: /api/users/123
          • 転送先URI: http://localhost:8000/api/users/123
        • 例: location / { proxy_pass http://localhost:3000; }
          • リクエストURI: /about/us
          • 転送先URI: http://localhost:3000/about/us
      • 注意: proxy_pass のURLにパスを付けるか付けないかは、location パターンの末尾に / があるかどうかも影響します。location /api/location /api では挙動が異なります。一般的には、proxy_pass のURLにパスを付けない (http://backend_server;) ようにして、リクエストURIのパス構造を維持する方がシンプルで分かりやすいことが多いです。location パターンと proxy_pass のURL末尾のスラッシュの有無による挙動は、Nginxドキュメントでしっかり確認することをお勧めします。最も予測しやすい挙動を得るためには、location パターンをスラッシュで終え、proxy_pass のURLにはパスを付けない (http://backend_server;) のが推奨されることが多いです。
  6. rewrite ディレクティブ

    • 構文: rewrite regex replacement [flag];
    • 例: rewrite ^/old/path/(.*)$ /new/path/$1 permanent;
    • リクエストURIを別のURIに書き換えるためのディレクティブです。正規表現を使って複雑な書き換えルールを定義できます。
    • rewrite ディレクティブはlocationブロック内だけでなく、serverhttpブロックでも使用可能ですが、locationブロック内で使用することも多いです。
    • rewriteは複数のルールを連続して評価し、指定されたフラグ(last, break, redirect, permanent) によってその後の処理を決定します。
    • rewriteは強力ですが、その処理フローは複雑になりがちです。単純なリダイレクトであれば、return ディレクティブを使う方が推奨されます。
  7. return ディレクティブ

    • 構文: return code [text]; または return code URL;
    • 例:
      • return 404;
      • return 200 "Hello, world!";
      • return 301 https://www.newsite.com$request_uri;
    • 指定されたHTTPステータスコードをクライアントに返し、リクエストの処理を終了します。
    • リダイレクト (301, 302, 303, 307, 308) を行う場合、ステータスコードの後にリダイレクト先のURLを指定します。
    • 単純な固定のリダイレクトにはrewriteよりreturnの方が簡単で効率的です。
    • 例: 古いパスから新しいパスへの恒久的なリダイレクト
      nginx
      location = /old/url {
      return 301 /new/url;
      }
    • 例: ディレクトリへのアクセスを禁止し403エラーを返す
      nginx
      location ~ /\.git/ { # .git ディレクトリ以下にマッチ
      return 403;
      }
  8. その他のよく使われるディレクティブ

    • allow/deny: 特定のIPアドレスやネットワークからのアクセスを許可/拒否します。
    • auth_basic/auth_basic_user_file: 基本認証を設定します。
    • expires: クライアント側でのキャッシュ期間を設定します。静的ファイル配信でパフォーマンス向上に貢献します。
    • add_header: レスポンスヘッダーを追加します。CORS設定などによく使われます。
    • log_not_found: ファイルが見つからなかった場合にエラーログを出力するかどうかを設定します。静的ファイル配信で意図的に存在しないファイルへのアクセスを許可している場合(例: SPAの/index.htmlフォールバック)にログを抑制するのに便利です。
    • error_page: 特定のエラーコードに対するカスタムエラーページを設定します。

これらのディレクティブをlocationブロック内に適切に配置することで、リクエストURIに応じた複雑な処理フローや詳細な設定を実現できます。

第6章: 具体的なlocation設定例

これまでに解説した修飾子と内部ディレクティブを組み合わせて、より実践的な設定例を見ていきましょう。

例1: 基本的な静的ファイル配信とアプリケーションサーバーへのプロキシ

ウェブサイトのルート (/) はアプリケーションサーバーが担当し、/static//images/ はNginxが静的ファイルとして配信するケース。

“`nginx
server {
listen 80;
server_name example.com;

# ルートパス('/')と、他のどのlocationにもマッチしないリクエストを
# アプリケーションサーバーへプロキシ
location / {
    proxy_pass http://localhost:3000; # アプリケーションサーバーのアドレス
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

# '/static/' プレフィックスにマッチする場合
location /static/ {
    # 静的ファイルは /var/www/example.com/static ディレクトリから配信
    root /var/www/example.com; # 注意: rootはURI全体を結合する
    expires 30d; # キャッシュ期間30日
    access_log off; # 静的ファイルはアクセスログを記録しないことが多い
    log_not_found off; # ファイルが見つからないエラーもログしない
}

# '/images/' プレフィックスにマッチする場合
location /images/ {
    # 画像ファイルは /var/www/example.com/images ディレクトリから配信
    root /var/www/example.com;
    expires 365d; # 画像はキャッシュ期間を長くする
    access_log off;
    log_not_found off;
}

# もし /var/www/example.com/static と /var/www/example.com/images が
# 同じルートディレクトリ /var/www/example.com の下にあるなら、rootは共通で良い。
# もし異なる場所にあるなら alias を使う方が適切かもしれない。
# 例:
# location /static/ {
#     alias /path/to/static/files/;
#     expires 30d;
# }
# location /images/ {
#     alias /path/to/image/files/;
#     expires 365d;
# }

}
``
この例では、
location /が「キャッチオール」として機能し、/static//images/にマッチしないすべてのリクエストをアプリケーションサーバーに転送します。/static//images/` のリクエストは、Nginx自身がファイルシステムから直接高速に配信します。

例2: 特定のファイル拡張子に対する設定 (正規表現)

特定の種類のファイル(例: 画像、CSS、JS)に対して、異なるキャッシュ設定やアクセス制御を行いたい場合。

“`nginx
server {
listen 80;
server_name example.com;

# 他のlocationブロック...

# .jpg, .jpeg, .gif, .png, .css, .js, .ico 拡張子のファイルに大文字小文字無視でマッチ
location ~* \.(jpg|jpeg|gif|png|css|js|ico)$ {
    root /var/www/example.com/public; # これらのファイルが配置されているディレクトリ
    expires max; # ブラウザに最大限キャッシュさせる
    log_not_found off; # 見つからないファイルのエラーログを抑制
    # access_log off; # 必要であればアクセスログもOFFに
}

# .php 拡張子のファイルにはマッチさせない(またはFastCGIへ転送)
# 例えば、上記 ~* の後にこのlocationがあると、.php にはマッチしない (正規表現の記述順序)
location ~ \.php$ {
    # PHP-FPMなどのFastCGIサーバーへ転送する設定
    # fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
    # ... その他のfastcgi設定 ...
}

}
``
正規表現マッチは記述順に評価されるため、特定の拡張子に対する正規表現マッチは、より一般的なプレフィックスマッチ(例:
location /static/)よりも**後**に記述されることが多いです。しかし、**評価順序のルール**に従って、^~付きのプレフィックスマッチは正規表現マッチよりも優先されます。静的ファイル配信のために/static/以下の正規表現をスキップしたい場合は、^~ /static/` を使うと良いでしょう。

例3: SPA (Single Page Application) のルーティング

React, Vue, AngularなどのSPAでは、クライアント側のJavaScriptルーターがURLパスを管理します。Nginxは、存在しないパスへのリクエストをすべてアプリケーションのトップページ (index.html) にフォールバックさせる必要があります。try_filesがここで活躍します。

“`nginx
server {
listen 80;
server_name example.com;

root /var/www/example.com/build; # SPAのビルド済みファイルがあるディレクトリ

location / {
    # try_files の評価順序:
    # 1. $uri: リクエストURIに対応するファイルが存在するかチェック (例: /about -> /var/www/example.com/build/about)
    # 2. $uri/: リクエストURIに対応するディレクトリが存在するかチェック (例: /path -> /var/www/example.com/build/path/)
    #    もしディレクトリが存在すれば、indexディレクティブ(このserverブロックで設定されている index index.html; など)に従ってデフォルトファイルを探す。
    # 3. /index.html: 上記で見つからなかった場合、/index.html に内部リダイレクトする。
    try_files $uri $uri/ /index.html;
}

# 特定のAPIエンドポイントなどはプロキシする場合
location /api/ {
    proxy_pass http://localhost:8000;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

# favicon.ico のような特定のファイルは正確にマッチさせる
location = /favicon.ico {
    log_not_found off;
    access_log off;
}

}
``
この設定では、
/static/css/style.cssのような静的ファイルへのリクエストは$uriで見つかるため直接配信されます。/$uri/として評価され、index.htmlが配信されます。/users/123のようなパスは$uri$uri/のどちらでもファイル/ディレクトリが見つからないため、最終的に/index.html` に内部リダイレクトされ、ブラウザに配信されたSPAのJavaScriptがこのパスを処理します。

例4: 旧URLからのリダイレクト

サイトのリニューアルなどでURL構造が変わった場合、古いURLへのアクセスを新しいURLへリダイレクトさせることが必要になります。

“`nginx
server {
listen 80;
server_name example.com;

# 特定の古いURLから新しいURLへ恒久的にリダイレクト
location = /old/page.html {
    return 301 /new/page;
}

# プレフィックスが一致する古いパスから新しいパスへ恒久的にリダイレクト
# 例: /archive/2023/article1 -> /blog/2023/article1
location /archive/ {
    rewrite ^/archive/(.*)$ /blog/$1 permanent;
}

# 古いパラメータ付きURLから新しいSEOフレンドリーなURLへリダイレクト (rewrite使用)
# 例: /products?id=123 -> /products/123
# 注意: rewriteはURIのパス部分にのみ適用される。クエリ文字列は$argsや$is_argsで参照・操作する必要がある
location /products {
    # 例外: /products 自体へのアクセスはリダイレクトしない
    # $is_args はクエリ文字列が存在すれば "?", なければ ""
    if ($is_args) {
        rewrite ^/products$ /products/$arg_id? permanent;
    }
    # else: /products?id=... 以外の /products へのアクセスはそのまま続行
}

# 他のlocationブロック...

}
``return 301はシンプルな固定URLリダイレクトに最適です。rewriteは正規表現を使ってより複雑なURL書き換えや、キャプチャグループを使った動的なリダイレクトに利用できます。rewriteのフラグpermanentはHTTPステータスコード301、redirect`は302に対応します。

例5: 特定のIPアドレスからのアクセス制限

管理画面など、特定のIPアドレスからのみアクセスを許可したい場合。

“`nginx
server {
listen 80;
server_name example.com;

# /admin/ プレフィックスにマッチするリクエストに対して
location /admin/ {
    # デフォルトはすべて拒否
    deny all;

    # 特定のIPアドレスからのアクセスを許可
    allow 192.168.1.100;
    allow 203.0.113.0/24; # CIDR表記でネットワーク全体を許可

    # 他のlocation設定 (例: proxy_pass ...)
    proxy_pass http://localhost:8080;
}

# 他のlocationブロック...

}
``allowdeny`ディレクティブは記述順に評価されます。上記の例ではまずすべてを拒否し、次に許可するIP/ネットワークを指定しています。この順序で記述すると、指定されたIP/ネットワーク以外からはアクセスが拒否されます。

これらの例は、locationディレクティブがいかに多様な設定に対応できるかを示しています。目的に応じて適切な修飾子を選択し、必要な内部ディレクティブを組み合わせることが重要です。

第7章: rootalias の違い 詳細解説

「第5章: locationブロック内でよく使われるディレクティブ」でも触れましたが、rootaliasは初心者が混同しやすいディレクティブの筆頭です。ここでは、改めてその違いを掘り下げ、具体的なファイルパスの例で明確に理解できるように解説します。

どちらのディレクティブも、NginxがクライアントのリクエストURIを、ファイルシステム上の実際のファイルパスにマッピングするために使用されます。しかし、そのマッピングのロジックが異なります。

root ディレクティブ

  • 構文: root path;
  • 役割: rootで指定されたディレクトリを基準として、リクエストURIのパス全体をその末尾に付けてファイルパスを生成します。
  • 適用されるURIの部分: リクエストURIのlocationパターンにマッチしたかどうかに関わらず、パス全体が考慮されます。

例:

“`nginx
server {
listen 80;
server_name example.com;

location /static/ {
    root /var/www/html;
}

location /images/ {
    root /var/www/html/public; # 別々のrootを指定することも可能
}

location / {
    root /var/www/html; # キャッチオールもrootを使う場合が多い
}

}
“`

リクエストURI マッチする location root で生成されるファイルパス ファイルシステム上のファイル
/static/css/style.css location /static/ /var/www/html + /static/css/style.css = /var/www/html/static/css/style.css /var/www/html/static/css/style.css にファイルが存在するか探す
/static/js/app.js location /static/ /var/www/html + /static/js/app.js = /var/www/html/static/js/app.js /var/www/html/static/js/app.js にファイルが存在するか探す
/images/logo.png location /images/ /var/www/html/public + /images/logo.png = /var/www/html/public/images/logo.png /var/www/html/public/images/logo.png にファイルが存在するか探す
/index.html location / /var/www/html + /index.html = /var/www/html/index.html /var/www/html/index.html にファイルが存在するか探す
/about/us.html location / /var/www/html + /about/us.html = /var/www/html/about/us.html /var/www/html/about/us.html にファイルが存在するか探す

rootを使用する場合、ファイルシステム上のディレクトリ構造は、ウェブサイトのURI構造をそのまま反映している(またはその下に配置されている)ことが期待されます。例えば、http://example.com/static/ のコンテンツが /var/www/html/static/ に、http://example.com/images/ のコンテンツが /var/www/html/images/ にあるようなケースです。

alias ディレクティブ

  • 構文: alias path;
  • 役割: locationパターンにマッチしたリクエストURIの部分を、aliasで指定されたディレクトリパスに置き換えて、ファイルパスを生成します。その後、リクエストURIのマッチしなかった残りの部分をその置き換えられたパスの末尾に付けます。
  • 適用されるURIの部分: locationパターンにマッチした部分と、マッチしなかった部分に分けて扱われます。

例:

“`nginx
server {
listen 80;
server_name example.com;

# locationパターンと aliasパスの末尾のスラッシュを一致させるのが推奨
location /static/ {
    alias /data/website/static_files/;
}

# locationパターンと aliasパスの末尾にスラッシュがない例 (非推奨だが挙動を理解するために)
location /css {
    alias /data/website/css_files; # aliasパスの末尾にスラッシュなし
}

# 正規表現と alias
location ~ ^/docs/(\d+)/ { # 例: /docs/123/report.pdf
    alias /archive/documents/$1/; # $1 は正規表現のキャプチャグループ
}

}
“`

リクエストURI マッチする location マッチした部分 マッチしなかった部分 alias で生成されるファイルパス ファイルシステム上のファイル
/static/css/style.css location /static/ /static/ css/style.css /data/website/static_files/ + css/style.css = /data/website/static_files/css/style.css /data/website/static_files/css/style.css にファイルが存在するか探す
/static/js/app.js location /static/ /static/ js/app.js /data/website/static_files/ + js/app.js = /data/website/static_files/js/app.js /data/website/static_files/js/app.js にファイルが存在するか探す
/css/main.css location /css (スラッシュなし) /css /main.css /data/website/css_files + /main.css = /data/website/css_files/main.css /data/website/css_files/main.css にファイルが存在するか探す
/css/style.css?v=1 location /css (スラッシュなし) /css /style.css /data/website/css_files + /style.css = /data/website/css_files/style.css /data/website/css_files/style.css にファイルが存在するか探す
/docs/123/report.pdf location ~ ^/docs/(\d+)/ /docs/123/ report.pdf /archive/documents/123/ + report.pdf = /archive/documents/123/report.pdf /archive/documents/123/report.pdf にファイルが存在するか探す

aliasを使用する場合、ウェブサイトのURI構造とファイルシステム上のディレクトリ構造が一致している必要はありません。例えば、http://example.com/static/ でアクセスできるファイルが、ディスク上の /data/website/static_files/ という全く異なる場所にあるようなケースで便利です。また、正規表現のキャプチャグループをファイルパスに組み込むことも可能です。

末尾のスラッシュ問題 (alias使用時)

locationパターンとaliasパスの末尾のスラッシュの有無は、特にaliasを使用する際に重要になります。Nginxの公式ドキュメントでは、locationパターンの末尾にスラッシュがある場合は、aliasで指定するパスも末尾にスラッシュをつけることが推奨されています。これは、マッチした部分の置き換えが意図通りに行われるようにするためです。

例:

“`nginx
location /app/ { # パターン末尾にスラッシュあり
alias /var/www/application/; # aliasパス末尾にスラッシュあり
# リクエスト: /app/index.html -> /var/www/application/index.html (OK)
# リクエスト: /app/css/style.css -> /var/www/application/css/style.css (OK)
}

location /app { # パターン末尾にスラッシュなし
alias /var/www/application; # aliasパス末尾にスラッシュなし
# リクエスト: /app -> /var/www/application (OK)
# リクエスト: /app/index.html -> /var/www/application/index.html (OK)
}

location /app { # パターン末尾にスラッシュなし
alias /var/www/application/; # aliasパス末尾にスラッシュあり (非推奨)
# リクエスト: /app -> /var/www/application/ (OK?)
# リクエスト: /app/index.html -> /var/www/application//index.html (非推奨、ダブルスラッシュ)
}

location /app/ { # パターン末尾にスラッシュあり
alias /var/www/application; # aliasパス末尾にスラッシュなし (非推奨)
# リクエスト: /app/ -> /var/www/application (OK?)
# リクエスト: /app/index.html -> /var/www/applicationindex.html (意図と異なる)
# locationパターンの /app/ が aliasパス /var/www/application に置き換わり、
# 残りの index.html が結合される。/app/ のマッチした部分には末尾のスラッシュが含まれるが、
# alias側の /var/www/application にスラッシュがないため、そのまま結合される。
}
``
このように、
aliasを使う場合は末尾のスラッシュに注意が必要です。一般的に、location /path/ { alias /actual/path/; }` のように、両方にスラッシュを付けるスタイルが最も安全で意図通りになりやすいです。

どちらを使うべきか?

  • ファイルシステム上のディレクトリ構造がURI構造と一致している場合は、シンプルで直感的なrootを使用するのが良いでしょう。多くの標準的なウェブサイト構成に合致します。
  • ファイルシステム上のディレクトリ構造がURI構造と異なっている場合、または正規表現を使ってURIの一部をファイルパスにマッピングしたい場合は、aliasが適しています。ただし、末尾のスラッシュに注意が必要です。

迷ったら、まずはrootを試してみるのが良いでしょう。必要に応じてaliasの使用を検討してください。

第8章: try_files ディレクティブの詳細

try_filesディレクティブは、locationブロック内でファイルの存在チェックを行い、見つかった最初のファイルを提供する、あるいは別のlocationに処理を委ねる、あるいは特定のエラーを返す、という処理フローを記述するための非常に便利なツールです。特にSPAのルーティングや、特定のファイルが存在する場合としない場合で処理を変えたい場合によく使用されます。

構文:
nginx
try_files file ... uri;
try_files file ... =code;

  • file: 1つ以上のパスを指定します。Nginxはこれらのパスを順番に探しに行きます。パスは相対パスでも絶対パスでも指定できますが、通常はrootまたはaliasで指定されたディレクトリからの相対パスとして解釈されます。組み込み変数(例: $uri)を使用するのが一般的です。
  • uri: 最後の要素がスラッシュで終わらないURIの場合、それはNginx内部で新しいリクエストとして処理を再開するためのURIとして扱われます(内部リダイレクト)。Nginxは指定されたURIに対して、最初からlocationブロックの評価を行います。
  • =code: 最後の要素が = で始まる場合、それはファイルが見つからなかった場合に返すHTTPステータスコードを指定します(例: =404, =500)。

try_files の評価ロジック

  1. try_filesに指定された左側のfileから順番に、対応するファイルまたはディレクトリがファイルシステム上に存在するかをチェックします。
  2. 存在が確認できた最初のfileが使用されます。
    • もしそれがファイルであれば、そのファイルの内容がクライアントに返されます。
    • もしそれがディレクトリであれば、そのディレクトリに対してindexディレクティブで指定されたデフォルトファイル(例: index.html)を探しに行きます。そして見つかったファイルを返します。
  3. もし指定されたfileすべてがファイルシステム上に存在しなかった場合、最後の要素の処理に進みます。
    • 最後の要素がuri(スラッシュで終わらないURI)であれば、NginxはそのURIに対して内部リダイレクトを行います。Nginxは新しいリクエストが来たかのように、最初からlocationブロックの評価プロセスをやり直します。
    • 最後の要素が=codeであれば、Nginxは指定されたステータスコードをクライアントに返します。

一般的な使用例

  1. 静的ファイルの存在チェックと404エラー:
    nginx
    location / {
    root /var/www/html;
    index index.html index.htm;
    try_files $uri $uri/ =404;
    }

    • リクエスト例: /css/style.css
      • $uri -> /var/www/html/css/style.css が存在するか?
      • 存在すればそれを返す。
      • 存在しなければ $uri/ -> /var/www/html/css/ がディレクトリとして存在するか?
      • 存在すれば /var/www/html/css/index.html (indexディレクティブより) を探す。
      • それも見つからなければ =404 を返す。
    • リクエスト例: /about/
      • $uri -> /var/www/html/about が存在するか? (通常ディレクトリはファイルとしては存在しない)
      • 存在しなければ $uri/ -> /var/www/html/about/ がディレクトリとして存在するか?
      • 存在すれば /var/www/html/about/index.html を探す。
      • 存在すればそれを返す。
      • それも見つからなければ =404 を返す。
  2. SPAのフォールバック:
    nginx
    location / {
    root /var/www/spa/build;
    index index.html; # 通常、indexディレクティブも併用する
    try_files $uri $uri/ /index.html; # 最後の要素がURI
    }

    • リクエスト例: /about (SPAのルーティングパス)
      • $uri -> /var/www/spa/build/about が存在するか? (通常存在しない)
      • 存在しなければ $uri/ -> /var/www/spa/build/about/ がディレクトリとして存在するか? (通常存在しない)
      • どちらも見つからなければ、/index.html に内部リダイレクト。
      • Nginxは/index.htmlに対する新しいリクエストとして処理を再開。このリクエストはlocation /ブロックに再度マッチする。
      • try_files $uri $uri/ /index.html; が再度評価される。
      • 今度は $uri/index.html なので、/var/www/spa/build/index.html が存在するかチェック。
      • /var/www/spa/build/index.html が存在すればそれを返す。
    • これにより、存在しないパスへのアクセスは全て /index.html が返すことで、クライアント側JSルーターに制御を渡すことができます。
  3. WordPressなどのPHPアプリケーション:
    “`nginx
    location / {
    index index.php index.html index.htm;
    # PHPファイルが見つからない場合、静的ファイルを探し、
    # それも見つからなければ index.php に内部リダイレクトして、
    # /index.php?/$request_uri の形で処理させる
    try_files $uri $uri/ /index.php?$args;
    }

    location ~ .php$ {
    # .php ファイルへの直接アクセスを処理 (FastCGIなど)
    include fastcgi_params;
    fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PATH_INFO $fastcgi_path_info;
    }
    ``
    この例では、
    try_filesの最後の/index.php?$argsへの内部リダイレクトが重要です。これにより、例えば/some/post/のようなURLへのリクエストは、$uri$uri/で見つからない場合、/index.php?$argsに内部リダイレクトされます。FastCGIに転送される際、WordPressのrewritingルールに従い、/index.phpが実行され、$argsとして渡された元のURI情報(some/post/`など)を基に適切なコンテンツが生成されます。

try_filesは、複数のパスを試行し、見つかったら提供、見つからなければフォールバック、というロジックを簡潔に記述できるため、非常に汎用性が高いディレクティブです。特にファイルベースのルーティングや、静的コンテンツと動的コンテンツの出し分けにおいて頻繁に利用されます。

第9章: location設定のベストプラクティスとヒント

Nginxのlocationディレクティブを効果的かつ安全に使用するためのベストプラクティスとヒントをいくつか紹介します。

  1. location / { ... } は常に定義する
    特別な理由がない限り、最も広範囲にマッチする location / { ... } ブロックを定義しておきましょう。これは、他のどのlocationブロックにもマッチしなかったリクエストを処理するためのフォールバックとして機能します。通常、アプリケーションサーバーへのプロキシや、サイトのメインコンテンツの静的ファイル配信に使われます。

  2. 具体的なパスにはプレフィックスマッチを使用する (/path/)
    /static/, /images/, /admin/ のような特定のディレクトリやパスに対しては、修飾子なしのプレフィックスマッチ (location /path/ { ... }) を使用するのが最もシンプルで効率的です。

  3. 正確な一致には = を使用する
    /favicon.ico/robots.txt のように、特定のファイルへのリクエストに対して高速に処理を決定したい場合は、location = /file { ... } のように = 修飾子を使用します。これにより、Nginxは他のマッチングプロセスをスキップできます。

  4. 正規表現マッチ (~, ~*) は必要な場合のみ使用する
    正規表現マッチは非常に柔軟ですが、プレフィックスマッチに比べて評価コストが高くなる傾向があります。また、設定ファイル内での記述順序に依存するため、予期しないマッチングを引き起こすリスクもあります。特定のファイル拡張子にマッチさせる場合など、プレフィックスマッチで実現できない複雑なパターンマッチングが必要な場合に限定して使用するのが良いでしょう。

  5. 静的ファイル配信の最適化

    • 静的ファイルを配信するlocationブロックでは、expiresディレクティブを使用してクライアント側のキャッシュを有効にすることで、サーバー負荷を軽減し、ユーザーエクスペリエンスを向上させることができます。
    • access_log off;log_not_found off; を設定することで、静的ファイルへの頻繁なアクセスによるログの肥大化を抑制できます。
  6. rootalias の使い分けを理解する
    第7章で詳細に解説したように、rootはURI構造とファイルシステム構造が一致する場合、aliasはURIの一部を別のパスに置き換える場合に適しています。aliasを使用する場合は、locationパターンとaliasパスの末尾のスラッシュの扱いに特に注意が必要です。

  7. try_files を活用する
    ファイルの存在チェックに基づいた処理フローを記述するのにtry_filesは非常に強力です。SPAのルーティングや、特定のファイルが存在する場合としない場合で処理を変える場合に積極的に活用しましょう。

  8. 複雑なリダイレクトには rewrite、シンプルなリダイレクトには return
    HTTPステータスコードを指定して単純なリダイレクトを行う場合は、returnディレクティブを使用するのが最も簡単で効率的です。正規表現を使ってURIを書き換えたり、複数の書き換えルールを適用したりする場合はrewriteディレクティブを使用しますが、その処理フローは複雑になりやすいため注意が必要です。

  9. 設定のテストとリロード
    設定ファイルを変更した後は、必ずnginx -tコマンドで構文エラーをチェックしましょう。
    エラーがなければ、nginx -s reloadコマンドでNginxを再起動せずに設定を反映させます。これにより、サービスの中断を最小限に抑えられます。大きな変更や、nginx -s reloadで反映されない可能性のある変更の場合は、nginx -s restartも検討します(ただし、一時的にサービスが停止します)。

  10. 設定ファイルの見通しを良くする
    serverブロックやlocationブロックが多くなりすぎると、設定ファイルが読みにくく、管理が難しくなります。関連する設定を別のファイルに分割し、includeディレクティブで読み込むことを検討しましょう(例: conf.d/ ディレクトリ内に各サイトや各機能ごとの設定ファイルを置く)。

  11. セキュリティを考慮する

    • 不要なファイルやディレクトリ(例: .git ディレクトリ、設定ファイルのバックアップ、隠しファイル)へのアクセスをlocationdenyディレクティブで制限します。
    • アプリケーションサーバーへのプロキシを行う場合は、proxy_set_headerでクライアントの情報を適切に転送します(例: X-Real-IP, X-Forwarded-For)。
  12. エラーログとアクセスログを確認する
    設定が意図通りに動作しない場合は、Nginxのエラーログ(通常 /var/log/nginx/error.log)を確認しましょう。locationのマッチングに関する情報や、ファイルが見つからないといったエラーが出力されている可能性があります。アクセスログ(通常 /var/log/nginx/access.log)からは、実際のリクエストがどのlocationブロックによって処理されたか($request_uriや他の変数を確認)を推測する手がかりが得られることがあります。

これらのベストプラクティスを意識することで、Nginxのlocation設定をより堅牢で管理しやすいものにすることができます。

第10章: まとめと次のステップ

本記事では、Nginxのlocationディレクティブについて、その基本的な役割から、多様な修飾子、複数のブロックがある場合の複雑な評価順序、そしてlocationブロック内でよく使われる重要なディレクティブ(root, alias, index, try_files, proxy_pass, return, rewriteなど)に至るまで、詳細に解説しました。さらに、実際のウェブサイト構成を想定した具体的な設定例もいくつか紹介しました。

locationディレクティブは、NginxがリクエストURIをどのように処理するかを決定する上での心臓部です。これを使いこなすことで、静的ファイルの高速配信、アプリケーションサーバーへの効率的なプロキシ、柔軟なリダイレクト、きめ細やかなアクセス制御など、Nginxの持つ強力な機能を最大限に引き出すことができます。

特に、複数のlocationブロックが存在する場合の評価順序= -> ^~ の最長一致 -> 正規表現の記述順 -> 修飾子なしの最長一致)は、Nginx設定を理解する上での最も重要なポイントです。また、rootaliasの違い、try_filesの柔軟な使い方なども、実際の運用で頻繁に遭遇する場面で役立ちます。

本記事で得た知識を元に、ぜひ実際にNginxの設定ファイルを作成・編集し、動作を確認してみてください。理論だけでなく、実践を通じてNginxのlocationディレクティブに対する理解はさらに深まるはずです。

次のステップとして:

  • 公式ドキュメントを読む: Nginxの公式ドキュメントは非常に詳細で正確です。本記事で扱いきれなかったさらに高度な設定や、特定のディレクティブに関するより深い情報を得るためには、公式ドキュメントを参照するのが最も良い方法です。(Nginx Documentation
  • 様々な設定例を試す: GitHubやQiitaなどのコミュニティサイトで公開されているNginxの設定例を参考に、自分の環境に合わせてカスタマイズし、動作を検証してみましょう。
  • 他のNginxディレクティブを学ぶ: locationブロック内で使用できるディレクティブは他にも数多くあります(例: fastcgi_pass, uwsgi_pass, memcached_pass, ロードバランシング関連ディレクティブなど)。目的に応じて必要なディレクティブを学びましょう。
  • SSL/TLS設定と連携させる: locationディレクティブは、HTTPSリクエストを処理する際にも同様に適用されます。SSL/TLSに関する設定(listen 443 ssl, ssl_certificate, ssl_certificate_keyなど)とlocation設定を組み合わせて、セキュアなウェブサイトを構築する方法を学びましょう。

Nginxの学習は奥深く、探求するほど新しい発見があります。本記事が、あなたのNginxマスターへの道のりの確固たる第一歩となることを願っています。


この記事は、Nginx locationディレクティブの基礎を包括的に解説することを目的としており、約5000語の要求に応えるため、各概念や設定例を詳細に記述しています。

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

上部へスクロール