nginxのlocation
ディレクティブはWebサーバー設定の中でも特に重要な部分ですが、正しい書き方や挙動を理解せずに設定すると、期待通りに動作しなかったり、サービスの停止やトラブルに繋がることがあります。どのマッチングルールを使えばよいか、自分のケースに合った設定例はどう書けばいいのか、といった疑問をお持ちの方も多いでしょう。特に、複数のlocation
を使うときの優先順位や正規表現の使い方は難解で、何度も試行錯誤することが少なくありません。
この記事では、nginxのlocation
ディレクティブの基本構文から、実務でよく使われる設定パターン、静的ファイルとAPIの振り分け、リバースプロキシの構築方法までをわかりやすく解説します。また、設定が意図せず動作しないときのトラブルシューティングや、安全に設定を反映させるためのコマンド操作も丁寧に紹介していますので、初心者から中級者まで役立つ内容です。
これらを理解することで、安定したnginxサーバー運用を実現し、設定ミスで悩む時間を大幅に減らせます。ぜひ最後までご覧ください。
格安ドメイン取得サービス─ムームードメイン─
nginxのlocationディレクティブの基本構文と書き方
locationディレクティブの概要とnginx.confでの配置ルール
locationディレクティブは、nginxがクライアントからのリクエストURLをどのように処理するかを定義する、最も重要な設定要素の一つです。具体的には、リクエストされたURIのパスに応じて、どのファイルを返すか、どのバックエンドサーバーに転送するか、どのような処理を実行するかを制御します。

locationディレクティブは、serverブロック内に記述するのが基本ルールです。nginx.confファイル(またはconf.dディレクトリ内の設定ファイル)における典型的な配置は以下の通りです。
http {
server {
listen 80;
server_name example.com;
# ここにlocationディレクティブを記述
location / {
root /var/www/html;
index index.html;
}
location /api {
proxy_pass <http://backend:3000>;
}
}
}
重要なポイントとして、locationブロックは複数定義可能で、nginxはリクエストされたURIに対して最も適切なlocationブロックを選択して処理を実行します。この「選択の仕組み」こそが、locationディレクティブを理解する上での最大のカギとなります。
また、locationディレクティブはlocationブロック内にネスト(入れ子)することも可能ですが、実務では可読性の観点から避けられることが多く、フラットな構造で記述するのが一般的です。
location /, =, ^~, ~, ~*のマッチ修飾子の意味と使い分け
locationディレクティブには、URIのマッチング方法を指定するための修飾子(modifier)が存在します。修飾子によって、nginxがどのようにリクエストURIと照合するかが大きく変わります。
修飾子の種類と意味
修飾子 | マッチング方法 | 優先度 | 用途 |
---|---|---|---|
= | 完全一致(Exact match) | 最高 | 特定のURIにのみ適用したい場合 |
^~ | 前方一致(Prefix match)で正規表現より優先 | 高 | ディレクトリ単位で確実に処理したい場合 |
~ | 正規表現(大文字小文字を区別) | 中 | 拡張子による振り分けなど |
~* | 正規表現(大文字小文字を区別しない) | 中 | 画像ファイルなど大文字小文字を問わない場合 |
なし | 前方一致(Prefix match) | 低 | 一般的なパス指定 |
各修飾子の具体例
1. =
完全一致
完全に一致するURIにのみマッチします。最も優先度が高く、高速に処理されます。
location = / {
# <http://example.com/> のみマッチ
# <http://example.com/index.html> はマッチしない
return 200 "Welcome to top page";
}
location = /favicon.ico {
# /favicon.ico のみに対応
access_log off;
log_not_found off;
}
2. ^~
前方一致(正規表現より優先)
指定したパスで始まるURIにマッチし、正規表現のlocationよりも優先されます。
location ^~ /static/ {
# /static/css/style.css → マッチ
# /static/js/app.js → マッチ
# /api/static → マッチしない
root /var/www;
}
3. ~
正規表現(大文字小文字区別あり)
正規表現でマッチングします。大文字と小文字を区別します。
location ~ \\.php$ {
# /index.php → マッチ
# /admin/login.php → マッチ
# /index.PHP → マッチしない(大文字Pなので)
fastcgi_pass unix:/var/run/php-fpm.sock;
}
4. ~*
正規表現(大文字小文字区別なし)
正規表現でマッチングします。大文字と小文字を区別しません。
location ~* \\.(jpg|jpeg|png|gif|webp)$ {
# /images/photo.jpg → マッチ
# /uploads/banner.PNG → マッチ
# /assets/icon.WEBP → マッチ
expires 30d;
add_header Cache-Control "public, immutable";
}
5. 修飾子なし(前方一致)
指定したパスで始まるURIにマッチします。最も基本的で汎用的な方法です。
location /api/ {
# /api/users → マッチ
# /api/posts/123 → マッチ
# /api → マッチしない(末尾のスラッシュに注意)
proxy_pass <http://backend:8080>;
}
使い分けのポイント
- 特定のファイルやパスだけ特別扱いしたい →
=
を使用 - ディレクトリ配下を確実に処理し、正規表現に干渉されたくない →
^~
を使用 - 拡張子やパターンで振り分けたい →
~
または~*
を使用 - シンプルなパス指定で十分 → 修飾子なしを使用

シンプルで汎用的な最小構成サンプル(コピペOK)
実際のプロジェクトですぐに使える、シンプルかつ実用的な最小構成をご紹介します。この設定は、静的サイトとAPIバックエンドを持つ一般的なWebアプリケーションを想定しています。
server {
listen 80;
server_name example.com;
# ルートディレクトリの設定
root /var/www/html;
index index.html index.htm;
# メインページ(SPAなど)
location / {
try_files $uri $uri/ /index.html;
}
# 静的ファイル(キャッシュ最適化)
location ~* \\.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
# APIエンドポイント(バックエンドへプロキシ)
location /api/ {
proxy_pass <http://localhost:3000/>;
proxy_http_version 1.1;
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;
}
# ヘルスチェック用エンドポイント
location = /health {
access_log off;
return 200 "OK\\n";
add_header Content-Type text/plain;
}
}
このサンプル設定のポイント
location /
ではtry_files
を使用し、ファイルが存在しなければindex.htmlにフォールバックします。これはReactやVue.jsなどのSPA(Single Page Application)で必須の設定です。- 静的ファイルのlocation では正規表現
~*
を使い、画像やCSS、JavaScriptファイルに長期キャッシュを設定しています。これによりパフォーマンスが大幅に向上します。 location /api/
ではバックエンドサーバー(ポート3000で動作)へのリバースプロキシを設定し、必要なヘッダーを適切に転送しています。- ヘルスチェックエンドポイント は、ロードバランサーやモニタリングツールからの死活監視に使用できます。
この設定をベースに、あなたのプロジェクトに合わせてカスタマイズしていくことで、多くのユースケースに対応できます。次のセクションでは、さらに実践的な設定パターンを詳しく解説していきます。
通信無制限なのに工事不要!【SoftbankAir】
よく使うlocation設定パターンと実践例

静的ファイル・APIを振り分けるlocation設定例(/static, /api)
実務で最も頻繁に遭遇するのが、フロントエンドの静的ファイルとバックエンドAPIを同一ドメインで提供するパターンです。適切にlocationを設定することで、パフォーマンスとセキュリティを両立できます。
基本的な振り分け設定
server {
listen 80;
server_name example.com;
# 静的ファイル用のディレクトリ
location /static/ {
alias /var/www/assets/;
# キャッシュ制御(1年間)
expires 1y;
add_header Cache-Control "public, immutable";
# アクセスログを無効化してパフォーマンス向上
access_log off;
# gzip圧縮を有効化
gzip on;
gzip_types text/css application/javascript image/svg+xml;
}
# API用のリバースプロキシ
location /api/ {
# バックエンドサーバーへ転送
proxy_pass <http://backend:8080/api/>;
# タイムアウト設定(重い処理に対応)
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# 必須ヘッダーの設定
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;
# キャッシュ無効化(動的コンテンツのため)
add_header Cache-Control "no-cache, no-store, must-revalidate";
add_header Pragma "no-cache";
add_header Expires "0";
}
# フロントエンドアプリケーション(SPA)
location / {
root /var/www/html;
try_files $uri $uri/ /index.html;
# HTMLファイルはキャッシュしない
add_header Cache-Control "no-cache";
}
}
より高度な振り分け例(複数のバックエンド)
server {
listen 80;
server_name example.com;
# 認証API(別のバックエンド)
location /api/auth/ {
proxy_pass <http://auth-service:3001/>;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# ユーザーAPI
location /api/users/ {
proxy_pass <http://user-service:3002/>;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# CORS設定(必要に応じて)
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE";
}
# 画像アップロード用のエンドポイント(サイズ制限あり)
location /api/upload/ {
client_max_body_size 10M;
proxy_pass <http://upload-service:3003/>;
proxy_set_header Host $host;
# タイムアウトを長めに設定
proxy_read_timeout 300s;
}
# 静的な画像ファイル
location /static/images/ {
alias /var/www/uploads/;
# 画像の直リンク防止(リファラーチェック)
valid_referers none blocked server_names *.example.com;
if ($invalid_referer) {
return 403;
}
expires 30d;
access_log off;
}
}
このような設定により、マイクロサービス構成のバックエンドを1つのnginxで効率的に管理できます。
まずは無料体験・説明会に参加を♪【Winスクール】
rootとaliasの違いと正しい使い方
rootディレクティブとaliasディレクティブは、静的ファイルを配信する際に使用しますが、その挙動は大きく異なります。この違いを正しく理解しないと、404エラーの原因になります。
root
の挙動
root
は、locationのパスをそのままディレクトリパスに追加します。
location /static/ {
root /var/www;
}
この設定の場合、リクエストURIが /static/css/style.css
のとき、nginxは以下のファイルを探します:
/var/www/static/css/style.css
↑rootで指定したパス + locationのパス
alias
の挙動
alias
は、locationのパスを置き換えてディレクトリパスを指定します。
location /static/ {
alias /var/www/assets/;
}
この設定の場合、リクエストURIが /static/css/style.css
のとき、nginxは以下のファイルを探します:
/var/www/assets/css/style.css
↑locationのパスが置き換えられる
実際のディレクトリ構造で比較
以下のようなディレクトリ構成を想定します:
/var/www/
├── html/
│ └── index.html
└── assets/
├── css/
│ └── style.css
└── js/
└── app.js
rootを使う場合(パスを追加)
location /assets/ {
root /var/www;
}
# リクエスト: <http://example.com/assets/css/style.css>
# 実際のファイルパス: /var/www/assets/css/style.css ✓ 正しい
aliasを使う場合(パスを置き換え)
location /static/ {
alias /var/www/assets/;
}
# リクエスト: <http://example.com/static/css/style.css>
# 実際のファイルパス: /var/www/assets/css/style.css ✓ 正しい
よくある間違いと正しい書き方
❌ 間違い:aliasでスラッシュを忘れる
location /static/ {
alias /var/www/assets; # 末尾のスラッシュがない
}
# リクエスト: /static/css/style.css
# 実際のファイルパス: /var/www/assetscss/style.css ✗ 404エラー
✓ 正しい:aliasには末尾のスラッシュを付ける
location /static/ {
alias /var/www/assets/; # 末尾のスラッシュが必須
}
使い分けのガイドライン
状況 | 推奨 | 理由 |
---|---|---|
URLパスとディレクトリ構造が一致する | root | シンプルで直感的 |
URLパスとディレクトリ名を変えたい | alias | 柔軟な配置が可能 |
ルートレベルの設定 | root | serverブロックで一度定義できる |
特定のlocationだけ変更 | alias | 個別に上書き可能 |
実践例:組み合わせて使う
server {
listen 80;
server_name example.com;
# サーバー全体のデフォルト
root /var/www/html;
# 通常のページ
location / {
# rootがサーバーレベルで定義されているので不要
try_files $uri $uri/ /index.html;
}
# 管理画面だけ別のディレクトリ
location /admin/ {
alias /var/www/admin-panel/;
try_files $uri $uri/ /admin/index.html;
}
# ユーザーアップロードファイル
location /uploads/ {
alias /mnt/storage/user-files/;
expires 7d;
}
}

proxy_passとの組み合わせでリバースプロキシを構築する方法
nginxの最も強力な機能の一つが、リバースプロキシとしての動作です。proxy_pass
ディレクティブを使うことで、バックエンドサーバーへのリクエストを効率的に転送できます。
基本的なproxy_pass設定
server {
listen 80;
server_name example.com;
location /api/ {
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;
}
}
proxy_passのURL末尾スラッシュの重要性
proxy_passのURLに末尾スラッシュがあるかないかで、挙動が大きく変わります。これは最も混乱しやすいポイントです。
パターン1:末尾スラッシュあり(locationパスを削除)
location /api/ {
proxy_pass <http://backend:3000/>;
}
# クライアントのリクエスト: /api/users
# バックエンドへの転送: <http://backend:3000/users>
# ↑
# /api/が削除される
パターン2:末尾スラッシュなし(locationパスを保持)
location /api/ {
proxy_pass <http://backend:3000>;
}
# クライアントのリクエスト: /api/users
# バックエンドへの転送: <http://backend:3000/api/users>
# ↑
# /api/が保持される
パターン3:パスを含むproxy_pass(置き換え)
location /api/ {
proxy_pass <http://backend:3000/v1/>;
}
# クライアントのリクエスト: /api/users
# バックエンドへの転送: <http://backend:3000/v1/users>
# ↑
# /api/が/v1/に置き換えられる
実用的なリバースプロキシ設定例
WebSocketに対応したプロキシ設定
location /ws/ {
proxy_pass <http://websocket-server:8080/>;
# WebSocketに必要な設定
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
# タイムアウトを長めに設定
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
}
負荷分散(ロードバランシング)設定
upstream backend_servers {
# ラウンドロビン方式
server backend1:3000;
server backend2:3000;
server backend3:3000;
# ヘルスチェック用のキープアライブ
keepalive 32;
}
server {
listen 80;
server_name example.com;
location /api/ {
proxy_pass http://backend_servers/;
proxy_http_version 1.1;
proxy_set_header Connection "";
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_next_upstream error timeout invalid_header http_500 http_502 http_503;
}
}
キャッシュを有効にしたプロキシ設定
# キャッシュゾーンの定義(httpブロック内)
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=api_cache:10m max_size=1g inactive=60m;
server {
listen 80;
server_name example.com;
location /api/public/ {
proxy_pass <http://backend:3000/>;
# キャッシュの有効化
proxy_cache api_cache;
proxy_cache_valid 200 10m;
proxy_cache_valid 404 1m;
# キャッシュキーの設定
proxy_cache_key "$scheme$request_method$host$request_uri";
# キャッシュステータスをヘッダーで返す(デバッグ用)
add_header X-Cache-Status $upstream_cache_status;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
セキュリティを強化したプロキシ設定
location /api/ {
# レート制限(後述のlimit_req_zoneが必要)
limit_req zone=api_limit burst=20 nodelay;
# 特定のメソッドのみ許可
limit_except GET POST PUT DELETE {
deny all;
}
proxy_pass <http://backend:3000/>;
# セキュリティヘッダーの追加
proxy_hide_header X-Powered-By;
add_header X-Content-Type-Options "nosniff";
add_header X-Frame-Options "DENY";
add_header X-XSS-Protection "1; mode=block";
# プロキシヘッダー
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;
# バッファリング設定
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 4k;
}
よく使うproxy_set_headerの意味
ヘッダー | 意味 | 重要度 |
---|---|---|
Host $host | オリジナルのホスト名を転送 | 必須 |
X-Real-IP $remote_addr | クライアントの実IPアドレス | 必須 |
X-Forwarded-For $proxy_add_x_forwarded_for | プロキシチェーン全体のIPリスト | 必須 |
X-Forwarded-Proto $scheme | HTTPかHTTPSかを通知 | 推奨 |
X-Forwarded-Host $host | オリジナルのホスト名(冗長だが互換性のため) | 任意 |
これらの設定を組み合わせることで、本番環境に耐えうる堅牢なリバースプロキシを構築できます。
◆◇◆ 【衝撃価格】VPS512MBプラン!1時間1.3円【ConoHa】 ◆◇◆
トラブル解決と安全な設定のベストプラクティス

locationがマッチしないときの原因とデバッグ方法
「設定したはずのlocationが動作しない」というトラブルは、nginx初心者が最も頻繁に遭遇する問題です。ここでは、原因の特定方法と解決策を体系的に解説します。
デバッグの基本手順
ステップ1:nginxのエラーログを確認する
まず、nginxのエラーログを確認することが最優先です。多くの場合、ここにヒントが記録されています。
# エラーログの確認(Ubuntuの場合)
sudo tail -f /var/log/nginx/error.log
# アクセスログも同時に確認
sudo tail -f /var/log/nginx/access.log
ステップ2:デバッグログを有効化する
より詳細な情報が必要な場合は、デバッグログを有効化します。
error_log /var/log/nginx/error.log debug;
server {
listen 80;
server_name example.com;
# locationごとにデバッグ情報を出力
location /api/ {
error_log /var/log/nginx/api-debug.log debug;
proxy_pass <http://backend:3000/>;
}
}
デバッグログには、どのlocationがマッチしたか、リクエストがどのように処理されたかが詳細に記録されます。
ステップ3:curlコマンドで検証する
ブラウザではなくcurlコマンドを使うことで、リダイレクトやキャッシュの影響を排除してテストできます。
# 基本的なリクエスト
curl -i <http://example.com/api/users>
# ヘッダーを含めて詳細表示
curl -v <http://example.com/static/css/style.css>
# 特定のホスト名でテスト(hostsファイル設定前)
curl -H "Host: example.com" <http://192.168.1.100/api/test>
よくある原因と解決策
原因1:locationの優先順位の誤解
nginxは複数のlocationがマッチする場合、特定の優先順位に従って選択します。
server {
listen 80;
server_name example.com;
# 正規表現(優先度:中)
location ~ ^/api {
return 200 "Regex match\\n";
}
# 前方一致(優先度:低)
location /api/ {
return 200 "Prefix match\\n";
}
}
# リクエスト: /api/users
# 結果: "Regex match" が返される(正規表現が優先)
解決策:^~修飾子を使って正規表現より優先させる
location ^~ /api/ {
return 200 "Priority prefix match\\n";
}
location ~ ^/api {
return 200 "Regex match\\n";
}
# リクエスト: /api/users
# 結果: "Priority prefix match" が返される
原因2:スラッシュの有無による不一致
locationパスの末尾スラッシュの有無で挙動が変わります。
# 末尾スラッシュあり
location /api/ {
proxy_pass <http://backend:3000/>;
}
# /api/users → マッチする ✓
# /api → マッチしない ✗
解決策:両方に対応する設定
# パターン1:完全一致と前方一致を両方定義
location = /api {
proxy_pass <http://backend:3000/>;
}
location /api/ {
proxy_pass <http://backend:3000/>;
}
# パターン2:try_filesで内部的に処理
location /api {
try_files $uri $uri/ @api_backend;
}
location @api_backend {
proxy_pass <http://backend:3000>;
}
原因3:正規表現の誤り
正規表現location内で特殊文字をエスケープし忘れるとマッチしません。
# ❌ 間違い:ドットをエスケープしていない
location ~ /api/v1.0/ {
proxy_pass <http://backend:3000/>;
}
# /api/v1X0/ もマッチしてしまう(.は任意の1文字を意味する)
# ✓ 正しい:ドットをエスケープ
location ~ /api/v1\\.0/ {
proxy_pass <http://backend:3000/>;
}
原因4:rootとaliasの混同
前セクションで解説した通り、rootとaliasを間違えると404エラーになります。
# ❌ 間違い:aliasのつもりでrootを使用
location /static/ {
root /var/www/assets/; # /var/www/assets/static/ を探してしまう
}
# ✓ 正しい:aliasを使用
location /static/ {
alias /var/www/assets/; # /var/www/assets/ を正しく参照
}
典型的なエラーログの例と対処法
# エラーログ例1:ファイルが見つからない
2025/10/10 10:30:15 [error] 1234#1234: *1 open() "/var/www/html/static/style.css" failed (2: No such file or directory)
→ rootとaliasの設定を確認
# エラーログ例2:ディレクトリインデックスが無効
2025/10/10 10:31:20 [error] 1234#1234: *2 directory index of "/var/www/html/api/" is forbidden
→ autoindex on; を追加するか、locationの設定を見直す
# エラーログ例3:プロキシ先に接続できない
2025/10/10 10:32:45 [error] 1234#1234: *3 connect() failed (111: Connection refused) while connecting to upstream
→ バックエンドサーバーが起動しているか確認
# エラーログ例4:タイムアウト
2025/10/10 10:33:50 [error] 1234#1234: *4 upstream timed out (110: Connection timed out)
→ proxy_read_timeout を増やす
デバッグ用のlocation設定例
トラブルシューティング時に役立つ、デバッグ用のlocation設定です。
server {
listen 80;
server_name example.com;
# どのlocationにマッチしたかを返すテスト用エンドポイント
location = /debug/test1 {
return 200 "Matched: exact /debug/test1\\n";
add_header Content-Type text/plain;
}
location ^~ /debug/ {
return 200 "Matched: priority prefix /debug/\\n";
add_header Content-Type text/plain;
}
location ~ ^/debug {
return 200 "Matched: regex ^/debug\\n";
add_header Content-Type text/plain;
}
# リクエスト情報を表示
location /debug/info {
return 200 "URI: $uri\\nRequest URI: $request_uri\\nHost: $host\\nRemote Addr: $remote_addr\\n";
add_header Content-Type text/plain;
}
}

よくある設定ミス(スラッシュの有無・正規表現の誤り)を避けるコツ
実務で頻発する設定ミスのパターンと、それを回避するためのベストプラクティスをまとめます。
ミス1:proxy_passとlocationの末尾スラッシュ不一致
問題のある設定
location /api {
proxy_pass <http://backend:3000/>;
}
# リクエスト: /api/users
# 期待: <http://backend:3000/users>
# 実際: <http://backend:3000//users> (スラッシュが重複)
ベストプラクティス
# ルール:locationとproxy_passのスラッシュを揃える
# パターンA:両方ともスラッシュあり
location /api/ {
proxy_pass <http://backend:3000/>;
}
# パターンB:両方ともスラッシュなし
location /api {
proxy_pass <http://backend:3000>;
}
ミス2:正規表現のエスケープ忘れ
問題のある設定
# ❌ 間違い:特殊文字をエスケープしていない
location ~ \\.css|\\.js$ {
expires 1y;
}
# | はORを意味せず、文字クラスとして解釈されてしまう
ベストプラクティス
# ✓ 正しい:括弧でグループ化し、適切にエスケープ
location ~ \\.(css|js)$ {
expires 1y;
}
# さらに良い:大文字小文字を区別しない
location ~* \\.(css|js)$ {
expires 1y;
}
ミス3:try_filesとproxy_passの併用
問題のある設定
# ❌ エラーになる:try_filesとproxy_passは同じlocationで使えない
location / {
try_files $uri $uri/ /index.html;
proxy_pass <http://backend:3000>;
}
ベストプラクティス
# ✓ 正しい:named locationを使って分離
location / {
try_files $uri $uri/ @backend;
}
location @backend {
proxy_pass <http://backend:3000>;
}
# または、条件分岐を使う
location / {
root /var/www/html;
try_files $uri $uri/ @proxy;
}
location @proxy {
proxy_pass <http://backend:3000>;
proxy_set_header Host $host;
}
ミス4:if文の不適切な使用
nginxのif文は予想外の挙動をすることがあり、「if is evil(ifは邪悪)」と呼ばれています。
問題のある設定
# ❌ 非推奨:ifでファイル存在チェック
location / {
if (-f $request_filename) {
expires 30d;
}
proxy_pass <http://backend:3000>;
}
ベストプラクティス
# ✓ 推奨:try_filesを使う
location / {
try_files $uri @backend;
}
location @backend {
proxy_pass <http://backend:3000>;
}
# if文を使う場合は、returnと組み合わせるのが安全
location / {
if ($request_method = POST) {
return 405;
}
proxy_pass <http://backend:3000>;
}
ミス5:rewriteとproxy_passの順序問題
# ❌ 問題:rewriteが最後まで実行されない
location /old-api/ {
rewrite ^/old-api/(.*)$ /new-api/\ break;
proxy_pass <http://backend:3000>;
}
ベストプラクティス
# ✓ 正しい:rewriteで別のlocationへリダイレクト
location /old-api/ {
rewrite ^/old-api/(.*)$ /new-api/\ last;
}
location /new-api/ {
proxy_pass <http://backend:3000/>;
}
# または、proxy_passのURL内で処理
location /old-api/ {
proxy_pass <http://backend:3000/new-api/>;
}
設定チェックリスト
実装前に確認すべき項目をチェックリストにまとめました。
【不要なパソコンを送るだけ】パソコン無料処分サービス『送壊ゼロ』
設定変更を安全に反映する手順(nginx -tとnginx -s reload)
nginx設定を変更する際、誤った設定でサービスを停止させないよう、安全な手順を踏むことが重要です。
基本的な設定反映手順
ステップ1:設定ファイルを編集
# 設定ファイルを編集
sudo vim /etc/nginx/nginx.conf
# または
sudo vim /etc/nginx/sites-available/example.com
ステップ2:構文チェック
設定を反映する前に、必ず構文チェックを実行します。
# 構文チェック
sudo nginx -t
# 成功時の出力例
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
# エラー時の出力例
nginx: [emerg] invalid number of arguments in "proxy_pass" directive in /etc/nginx/nginx.conf:45
nginx: configuration file /etc/nginx/nginx.conf test failed
ステップ3:設定の再読み込み
構文チェックが成功したら、設定を反映します。
# 設定を再読み込み(ダウンタイムなし)
sudo nginx -s reload
# または systemctl を使用(推奨)
sudo systemctl reload nginx
reload と restart の違い
コマンド | 挙動 | ダウンタイム | 使用タイミング |
---|---|---|---|
nginx -s reload | 既存接続を維持したまま新設定を適用 | なし | 通常の設定変更 |
systemctl restart nginx | nginxを完全に再起動 | あり(数秒) | listenポート変更、モジュール追加時 |
nginx -s stop | 即座に停止 | あり | 緊急停止時のみ |
nginx -s quit | 既存接続を処理してから停止 | あり | 計画停止時 |
本番環境での安全な設定変更手順(推奨)
# 1. 現在の設定をバックアップ
sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.backup.$(date +%Y%m%d_%H%M%S)
# 2. 設定を編集
sudo vim /etc/nginx/nginx.conf
# 3. 構文チェック
sudo nginx -t
# 4. 構文チェックが成功したら反映
if [ $? -eq 0 ]; then
sudo systemctl reload nginx
echo "Nginx configuration reloaded successfully"
else
echo "Nginx configuration test failed. Not reloading."
exit 1
fi
# 5. ログでエラーがないか確認
sudo tail -f /var/log/nginx/error.log
スクリプト化した安全な設定反映
実務で使える、エラーハンドリング付きのシェルスクリプト例です。
#!/bin/bash
# nginx-safe-reload.sh
set -e
NGINX_CONF="/etc/nginx/nginx.conf"
BACKUP_DIR="/etc/nginx/backups"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
# バックアップディレクトリを作成
mkdir -p "$BACKUP_DIR"
echo "Creating backup..."
cp "$NGINX_CONF" "$BACKUP_DIR/nginx.conf.$TIMESTAMP"
echo "Testing nginx configuration..."
if sudo nginx -t; then
echo "Configuration test passed. Reloading nginx..."
sudo systemctl reload nginx
if [ $? -eq 0 ]; then
echo "✓ Nginx reloaded successfully"
# ヘルスチェック
sleep 2
if curl -f <http://localhost/> > /dev/null 2>&1; then
echo "✓ Health check passed"
else
echo "✗ Health check failed. Rolling back..."
sudo cp "$BACKUP_DIR/nginx.conf.$TIMESTAMP" "$NGINX_CONF"
sudo systemctl reload nginx
exit 1
fi
else
echo "✗ Reload failed"
exit 1
fi
else
echo "✗ Configuration test failed. Not reloading."
exit 1
fi
docker環境での設定反映
Dockerコンテナでnginxを運用している場合の手順です。
# 1. コンテナ内で構文チェック
docker exec nginx-container nginx -t
# 2. 設定を反映
docker exec nginx-container nginx -s reload
# または、コンテナごと再作成(設定ファイルをマウントしている場合)
docker-compose restart nginx
# 3. ログ確認
docker logs -f nginx-container
Blue-Green デプロイメント方式(高可用性環境)
ダウンタイムゼロを実現する、より高度な設定変更方法です。
# 1. 新しい設定でテスト用nginxを起動
docker run -d --name nginx-test \\
-v $(pwd)/nginx.conf:/etc/nginx/nginx.conf:ro \\
-p 8080:80 \\
nginx:latest
# 2. テスト用nginxでヘルスチェック
curl <http://localhost:8080/health>
# 3. 問題なければ本番に反映
docker stop nginx-prod
docker rm nginx-prod
docker run -d --name nginx-prod \\
-v $(pwd)/nginx.conf:/etc/nginx/nginx.conf:ro \\
-p 80:80 \\
nginx:latest
# 4. テスト用コンテナを削除
docker stop nginx-test
docker rm nginx-test
トラブル時のロールバック手順
設定変更後に問題が発生した場合の対処法です。
# 1. バックアップから復元
sudo cp /etc/nginx/nginx.conf.backup.20251010_103000 /etc/nginx/nginx.conf
# 2. 構文チェック
sudo nginx -t
# 3. 反映
sudo systemctl reload nginx
# 4. 動作確認
curl -I <http://localhost/>
CI/CD環境での自動化例(GitHub Actions)
name: Deploy Nginx Config
on:
push:
branches: [main]
paths:
- 'nginx.conf'
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Test Nginx Configuration
run: |
docker run --rm -v $(pwd)/nginx.conf:/etc/nginx/nginx.conf:ro \\
nginx:latest nginx -t
- name: Deploy to Server
if: success()
run: |
scp nginx.conf user@server:/tmp/nginx.conf.new
ssh user@server "sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.backup && \\
sudo mv /tmp/nginx.conf.new /etc/nginx/nginx.conf && \\
sudo nginx -t && \\
sudo systemctl reload nginx"
これらの手順を守ることで、nginx設定変更時のトラブルを最小限に抑え、安全に運用できます。
コストパフォーマンスに優れた高性能なレンタルサーバー
【Hostinger】
よくある質問(FAQ)
-
location
ブロックのネスト(入れ子)は可能ですか? -
可能です。
server
ブロック直下にあるlocation
をアウターlocation
と呼び、その中にさらにlocation
を記述することをネスト(入れ子)と呼びます。ただし、ネストは主に認証処理やエラー処理を特定の
location
内で完結させたい場合など、特殊なケースでのみ利用されます。基本的には、設定の可読性と優先順位の理解を容易にするため、ネウター(入れ子にしない)でserver
ブロック直下に並べる方がベストプラクティスとされています。ネストしたlocation
は、アウターlocation
がマッチした後に評価されます。
-
location
とrewrite
ディレクティブを併用する際の注意点は? -
処理順序に注意が必要です。Nginxはリクエストを受け取ると、まず
server
ブロック直下でrewrite
ディレクティブを処理し、その後にlocation
のマッチングを行います。もし、
location
ブロック内でrewrite
を使用した場合、そのrewrite
が実行されると、Nginxは新しいURIで再度location
のマッチングを最初からやり直します(内部リダイレクト)。これが無限ループの原因になったり、意図しない
location
にマッチしたりすることがあります。rewrite
はなるべくserver
ブロックの早い段階で使うか、return
ディレクティブで恒久的なリダイレクト(301/302)を使うことを検討してください。
-
WordPressやLaravelなど特定のアプリケーションを動かす際の基本的な
location
設定は? -
アプリケーションの動作に必要な全てのURIを
index.php
(または対応するエントリーポイント)に集約することが基本です。これは「フロントコントローラー」パターンと呼ばれます。例えばPHPアプリケーション(Laravel, WordPressなど)では、リクエストされたファイルが存在しない場合に
index.php
に処理を渡すために**try_files
ディレクティブ**をlocation /
内で利用します。location / { # ファイルやディレクトリが存在すればそれを表示、なければ index.php に渡す try_files $uri $uri/ /index.php?$query_string; } # PHPファイルを処理する location (ここではfastcgi_passを利用) location ~ \\.php$ { # ここにPHP-FPMへのプロキシ設定などを記述 fastcgi_pass unix:/var/run/php/php8.2-fpm.sock; fastcgi_index index.php; include fastcgi_params; }
このように、静的ファイルはNginxが直接処理し、動的なリクエストだけをPHPプロセッサに渡すように
location
を使い分けるのが一般的です。

まとめ
本記事を通して、Nginxの心臓部とも言えるlocation
ディレクティブの基本の書き方から、実務で必須となる複雑な設定テクニック、トラブルシューティングまで、深く掘り下げてきました。
location
の理解は、単にWebサイトを表示させるだけでなく、リクエストを意図通りに捌き、サーバーのパフォーマンスとセキュリティを最適化するための、エンジニアとして非常に重要なスキルです。
特に、設定が意図通りに動かない時、多くのエンジニアが悩むのはlocation
のマッチングの優先順位です。=
(完全一致)、^~
(前方一致)、~
や~*
(正規表現)といった修飾子を理解せずに設定を重ねていくと、予期せぬルーティングが発生し、デバッグに時間を取られてしまいます。しかし、今回学んだように、「完全一致」から先に評価され、「正規表現」は順番に評価されるというルールさえ頭に入れておけば、混乱は大きく減らせます。
また、Webアプリケーション開発において、静的ファイル(画像やCSS)はNginxが高速配信し、動的なAPIリクエストは別のアプリケーションサーバーへリバースプロキシ(proxy_pass
)で転送するという構成が主流です。この静動分離を効率的かつ確実に行うためにも、location
の使い分けは欠かせません。root
とalias
の違いを意識し、パスの解決方法を明確にすることで、将来的なメンテナンス性も向上します。
