2026年6月30日
2026年6月30日
Nginxのtry_filesの使い方をWordPressの設定例で解説
Nginx の try_files は、並べたファイルやディレクトリを左から順に探し、最初に見つかったものを返し、どれも無ければ最後に書いた URI へ内部転送するか、指定したステータスコードを返すディレクティブです。WordPress では try_files $uri $uri/ /index.php?$args; の1行で、実在する画像や CSS はそのまま配信し、それ以外の投稿ページなどを index.php に渡す、パーマリンクの仕組みを実現しています。この記事では、書式と評価の順番、WordPress での定番の書き方とその意味、PHP の location に try_files $uri =404; を入れる理由、よくある失敗とエラーログの読み方を説明します。
書式と評価の順番
try_files ファイル1 ファイル2 ... 最後の引数;
server か location の中に書きます。Nginx は root(または alias)で指定したディレクトリを基準に、引数を左から順に確かめます。
$uriのような引数は「そのパスのファイルがあるか」を確かめる- 末尾が
/の引数($uri/)は「そのパスのディレクトリがあるか」を確かめる。見つかるとindexディレクティブに従ってindex.phpやindex.htmlが探される - 最後の引数だけは特別で、「探す対象」ではなく「どれも見つからなかったときの行き先」になる。URI を書けばその URI へ内部転送し、
=404のように書けばそのステータスコードを返す
ここで言う内部転送は、ブラウザに見える URL は変えずに、Nginx の中で別の URI として処理し直すことです。リダイレクト(301 や 302)とは違い、訪問者のアドレスバーは元の URL のままです。転送された URI は改めて location の照合からやり直されるため、/index.php に転送されたリクエストは、PHP 用の location ~ \.php$ で処理されます。
WordPress での定番の書き方
server {
listen 443 ssl;
server_name example.com;
root /var/www/example.com;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
try_files $uri =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php/php-fpm.sock; # 実際のソケット名に合わせる
}
}
location / の1行は、次の順に処理されます。
/wp-content/uploads/2026/10/photo.jpgのように実在するファイルなら、そのまま静的ファイルとして返す/wp-admin/のように実在するディレクトリなら、その中のindex.phpを探す/sample-page/のように実在しないパスなら、/index.php?$argsへ内部転送し、WordPress がパーマリンクを解釈してページを組み立てる
$args はクエリ文字列(? 以降)です。これを付けないと、検索の ?s=キーワード やプレビューの ?preview=true などが WordPress に届きません。/index.php$is_args$args と書く例もあり、こちらはクエリが無いときに ? を付けない書き方です。どちらでも WordPress は動きます。
Apache の .htaccess で WordPress が書き込む RewriteCond %{REQUEST_FILENAME} !-f などの記述は、Nginx ではこの try_files が受け持ちます。Nginx は .htaccess を読まないため、管理画面でパーマリンク設定を保存しても、Nginx 側にこの行が無ければ投稿ページは 404 のままです。
PHP の location に try_files $uri =404 を入れる理由
PHP 用の location にある try_files $uri =404; は、「実在しない PHP ファイルへのリクエストを PHP-FPM に渡さない」ための行です。PHP の設定によっては、/wp-content/uploads/image.jpg/x.php のような存在しないパスを渡されたとき、パスをさかのぼって image.jpg を PHP として実行しようとすることがあります。アップロードされた画像に悪意のあるコードが仕込まれていると、それが実行されるおそれがあります。
try_files $uri =404; があれば、x.php というファイルが実在しない時点で 404 を返すため、この経路を塞げます。あわせて、アップロード用のディレクトリでは PHP を実行させない設定も入れておくと、より安全です。
location ~* ^/wp-content/uploads/.*\.php$ {
deny all;
}
正規表現の location は設定ファイルに書いた順に照合されるため、この location は PHP 用の location ~ \.php$ より前に書きます。
サブディレクトリに WordPress を置く場合
https://example.com/blog/ のように WordPress を /blog に置く場合は、location と転送先の両方を合わせます。
location /blog/ {
try_files $uri $uri/ /blog/index.php?$args;
}
転送先を /index.php のままにすると、ドキュメントルート直下の別の index.php が呼ばれたり、ファイルが無くてエラーになったりします。
よくある失敗とエラーログの読み方
設定を変える前に /etc/nginx をバックアップし、変更後は sudo nginx -t && sudo systemctl reload nginx で構文を確かめてから反映します。うまく動かないときは、エラーログ(多くの環境で /var/log/nginx/error.log)を見ると原因の見当が付きます。
rewrite or internal redirection cycle と出る
エラーログに rewrite or internal redirection cycle while internally redirecting to "/index.php" と記録され、訪問者には 500 が返る状態です。最後の引数の転送先がさらに同じ try_files に戻り、無限に転送が続いています。よくある原因は次の順です。
rootのパスが間違っていて、index.php自体が見つからない- PHP 用の
locationが無い、または正規表現が合っておらず、/index.phpが再びlocation /で処理されている - サブディレクトリ設置で、転送先のパスが実際の配置と合っていない
ls -l で root に書いたパスに index.php があるか、Nginx の実行ユーザーに読み取り権限があるかを確認します。
PHP のソースがダウンロードされる
/index.php へ転送された後に処理する PHP 用の location が無いと、Nginx は index.php をただのファイルとして返してしまい、ソースコードがそのまま表示またはダウンロードされます。wp-config.php の中身が見える可能性もあるため、設定変更の直後は curl -I https://example.com/ で Content-Type が text/html になっているかを確認してください。
静的ファイルの location で XML や robots.txt が 404 になる
画像や CSS 用の location ~* \.(css|js|png|jpe?g|gif|webp|svg|xml|txt)$ { try_files $uri =404; } のように、拡張子でまとめて =404 にすると、PHP へ渡らなくなります。WordPress の robots.txt や、SEO プラグインやコアが出力する XML サイトマップは、実在するファイルではなく WordPress が動的に生成しているため、このように書くと 404 になります。静的ファイル用の location に xml や txt を含めないか、最後の引数を /index.php?$args にします。
location ~* \.(css|js|png|jpe?g|gif|webp|svg|woff2?)$ {
try_files $uri =404;
expires 30d;
access_log off;
}
画像を =404 で返すと、存在しない画像へのリクエストで毎回 WordPress が起動するのを防げるため、負荷の軽減にもなります。ただし、画像を動的に生成するプラグインを使っている場合は、その仕組みと合うか確認してください。
alias と組み合わせて意図しないパスになる
location の中で root の代わりに alias を使うと、try_files の扱いが直感と異なる場合があり、Nginx の不具合報告としても知られています。WordPress の設定では alias を使わず、root で書くほうがつまずきにくくなります。
古い if (!-e $request_filename) の設定を引き継いでいる
古い記事では if (!-e $request_filename) { rewrite ^ /index.php last; } のような書き方を見かけます。これは try_files が無かったころの方法で、今は try_files に置き換えるのが一般的です。location の中の if は思わぬ動きをすることがあるため、移行するときに見直す価値があります。
設定の書き方は Nginx の版が変わってもほぼ同じですが、PHP-FPM のソケット名や設定ファイルの場所は OS と PHP の版で異なります(2026年10月現在)。本番に入れる前に、ステージング環境で投稿ページ・固定ページ・検索・管理画面・サイトマップの表示まで確認しておくと安心です。
まとめ
try_filesは左から順に探し、最後の引数だけが「見つからなかったときの行き先」になる- WordPress は
try_files $uri $uri/ /index.php?$args;でパーマリンクを実現する。$argsを忘れると検索などが動かない - PHP 用の
locationにはtry_files $uri =404;を入れ、アップロード用ディレクトリでの PHP 実行を禁止する - サブディレクトリ設置では
locationと転送先の両方をそのパスに合わせる internal redirection cycleはrootと PHP 用locationの不備を疑う- 静的ファイル用の
locationにxmlやtxtを含めると、動的なサイトマップや robots.txt が 404 になる