症状
nginxで静的ファイル(CSS、JavaScript、画像など)にアクセスすると404 Not Foundが返される
結論:まずこれを確認
nginx -Tで実際に読み込まれている設定を確認rootまたはaliasのパスが実際のファイルパスと一致しているか確認- ファイルとディレクトリのパーミッションを確認(nginxユーザーが読めるか)
トラブルシューティングフロー
flowchart TD
A[静的ファイルが404] --> B{error.logを確認}
B -->|No such file or directory| C[パス設定を確認]
B -->|Permission denied| D[パーミッション確認]
B -->|エラーなし| E[access.logを確認]
C --> F{root/aliasの設定}
F -->|rootを使用| G[rootセクションへ]
F -->|aliasを使用| H[aliasセクションへ]
D --> I[パーミッションセクションへ]
E --> J[リクエストが届いているか確認]
よくある原因
- rootパスの誤り - rootディレクティブのパスがファイルの実際の場所と異なる
- aliasの末尾スラッシュ - aliasディレクティブで末尾スラッシュの有無が不一致
- パーミッション不足 - nginxの実行ユーザーがファイルを読み取れない
- SELinuxの制限 - SELinuxがファイルアクセスをブロックしている(RHEL/CentOS系)
- locationブロックの優先順位 - 別のlocationブロックが先にマッチしている
- シンボリックリンクの設定 -
disable_symlinksが有効になっている - try_filesの設定ミス - 静的ファイルの前にバックエンドへ転送している
確認手順
ステップ1: エラーログを確認する
# 最新のエラーログを確認
sudo tail -50 /var/log/nginx/error.log
# 特定のファイル名でフィルタ
sudo grep "ファイル名" /var/log/nginx/error.log
🔍 チェックポイント: No such file or directory または Permission denied のメッセージを探す
ステップ2: 実際の設定を確認する
# 読み込まれている設定を全て表示
sudo nginx -T
# 設定ファイルのシンタックスチェック
sudo nginx -t
🔍 チェックポイント: root または alias の値をメモする
ステップ3: ファイルパスを検証する
# 設定から読み取ったパスにファイルが存在するか確認
ls -la /設定で指定したパス/ファイル名
# rootの場合: root + URI がファイルパスになる
# 例: root /var/www/html; で /css/style.css へアクセス
# → /var/www/html/css/style.css を探す
ls -la /var/www/html/css/style.css
# aliasの場合: alias がURIの該当部分を置き換える
# 例: location /static/ { alias /var/www/files/; }
# → /static/image.png は /var/www/files/image.png を探す
ls -la /var/www/files/image.png
🔍 チェックポイント: ファイルが存在し、パスが正しいことを確認
ステップ4: パーミッションを確認する
# nginxの実行ユーザーを確認
ps aux | grep nginx
# ファイルのパーミッションを確認
ls -la /var/www/html/css/style.css
# ディレクトリのパーミッションを再帰的に確認
namei -l /var/www/html/css/style.css
🔍 チェックポイント: nginxユーザー(通常 nginx または www-data)がすべてのディレクトリに対して x(実行)権限、ファイルに対して r(読み取り)権限を持っている
ステップ5: SELinuxを確認する(RHEL/CentOS系のみ)
# SELinuxの状態を確認
getenforce
# httpd_sys_content_t のコンテキストを確認
ls -Z /var/www/html/
# 拒否されたログを確認
sudo ausearch -m avc -ts recent
🔍 チェックポイント: Enforcing の場合、ファイルに httpd_sys_content_t コンテキストがあるか確認
ステップ6: locationブロックの優先順位を確認する
# 設定を確認し、該当URIにマッチするlocationを特定
sudo nginx -T | grep -A 10 "location"
🔍 チェックポイント: より具体的な(または正規表現の)locationブロックが先にマッチしていないか確認
nginx の location マッチング優先順位:
=完全一致^~前方一致(正規表現より優先)~/~*正規表現- 前方一致(最長マッチ)
NG行動(やってはいけないこと)
- chmod 777 を使う - セキュリティリスク。適切な権限(644 for files, 755 for dirs)を設定する
- SELinuxを無効化する - 代わりにコンテキストを正しく設定する
- 設定変更後にreloadしない -
nginx -s reloadを忘れると変更が反映されない - error.logを確認せずに設定を変更する - 原因を特定してから修正する
- 本番環境で直接設定を編集する - 必ず
nginx -tでテストしてからreload
よくある質問(FAQ)
Q1: rootとaliasの違いは?
A: root はlocationのURIをそのまま追加する。alias はlocationで指定した部分を置き換える。
# root の場合
location /images/ {
root /var/www;
}
# /images/photo.jpg → /var/www/images/photo.jpg
# alias の場合
location /images/ {
alias /var/www/photos/;
}
# /images/photo.jpg → /var/www/photos/photo.jpg
Q2: aliasで末尾スラッシュは必要?
A: locationが /images/ のようにスラッシュで終わる場合、aliasも /var/www/photos/ のようにスラッシュで終わる必要がある。不一致だとパスが正しく構成されない。
Q3: 特定のファイルだけ404になる
A: ファイル名に特殊文字(スペース、日本語など)が含まれていないか確認。また、.htaccess は nginx では無視されるため、Apache からの移行時に注意。
関連するエラー・症状
- (関連記事準備中)
- (関連記事準備中)
- (関連記事準備中)
解決しない場合
公式ドキュメント
確認すべきログファイル
/var/log/nginx/error.log- エラーの詳細/var/log/nginx/access.log- リクエストの到達確認/var/log/audit/audit.log- SELinux拒否ログ(RHEL系)
次に調べるキーワード
nginx try_files 404nginx location prioritynginx symlink permission