やりたかったこと
VPSにnginxを入れてNext.jsのビルド済み静的ファイルを配信しようとしたら、どのURLを叩いても404 Not Foundしか返ってこなかった。設定ファイルはドキュメントのコピペなのに全然動かなくて、原因を探すのに2時間かかった。
環境
- Ubuntu 22.04
- nginx 1.18.0
- Next.js 14.x(静的エクスポート、
out/ディレクトリに出力)
nginxの404が出る主な原因
原因1: rootパスが存在しないか空
server {
listen 80;
server_name example.com;
root /var/www/html/out;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
root に指定したディレクトリが実際にあるか確認する。
ls -la /var/www/html/out
ディレクトリが存在しない・空だと問答無用で404になる。Next.jsなら npm run build のあとに npm run export(またはOutputの設定)を実行してから配置する必要があった。
原因2: SPAなのにtry_filesが=404で終わっている
# SPAで全ページ404になるパターン
location / {
try_files $uri $uri/ =404;
}
# 正しい設定
location / {
try_files $uri $uri/ /index.html;
}
=404 を最後に書くと、ファイルが直接存在しないURLはすべて404になる。React/Next.js/Vue.jsのSPAはパスがファイルに対応していないので、/index.html にフォールバックさせる必要がある。
原因3: ファイルのパーミッションが足りない
# nginxはwww-dataユーザーで動いている
ls -la /var/www/html/out/
# 755または644以上が必要
chmod -R 755 /var/www/html/out
chown -R www-data:www-data /var/www/html/out
ownerがrootのままだとnginxが読めずに403や404が返ることがある。
原因4: rootとaliasの挙動の違い
# rootはlocationのパスを含めたパスでファイルを探す
location /static/ {
root /var/www/files;
# /static/foo.js → /var/www/files/static/foo.js を探す
}
# aliasはlocationのパスを除いたパスで探す
location /static/ {
alias /var/www/files/;
# /static/foo.js → /var/www/files/foo.js を探す
}
root を使うと /static/ ディレクトリがファイルパスに含まれてしまう。意図によってどちらを使うか決める必要がある。
試したこと・うまくいかなかったこと
nginx -tをやらずに再起動を繰り返した
設定を直すたびに systemctl restart nginx していたが、何も変わらなかった。
しばらくして気づいたが、設定に構文エラーがあってnginxが古い設定のまま動き続けていた。
# 構文チェックを先にやる
nginx -t
# エラーがなければリロード
systemctl reload nginx
nginx -t が FAILED のままでは reload しても restart しても設定は更新されない。
エラーログを見ていなかった
404の原因を設定ファイルだけ見て探していたが、エラーログを見たら一発でわかった。
tail -f /var/log/nginx/error.log
2026/06/07 10:23:14 [error] 1234#1234: *1 "/var/www/html/out/about/index.html" is not found
ログを最初から見ていれば30分は無駄にしなかった。
解決策
nginx -t で構文エラーを確認し、rootのパスとファイルのパーミッションを修正したら直った。
# 確認の手順
nginx -t
ls -la /var/www/html/out/index.html
chown -R www-data:www-data /var/www/html/out
chmod -R 755 /var/www/html/out
systemctl reload nginx
# ログで確認
tail -f /var/log/nginx/error.log
エラーログに is not found が出ていたら rootのパスかパーミッションが原因。Permission denied が出ていたら chmod/chown が必要。
ハマったポイント
-
nginx -tを最初にやらなかったせいで、設定が反映されていないまま何度も確認ループした -
rootとaliasの動作が違うことを知らなくて、同じパスを書いているのに404になるケースに遭遇した - SPAで
try_files $uri $uri/ =404を使っていたせいで直リンクが全部404になった。/index.htmlへのフォールバックが必要だった -
chownでオーナーを変えたのにchmodを忘れていて、パーミッション不足で404が続いた - エラーログを後から見たら原因が一行で書いてあった。最初にログを見る習慣を付けるべきだった
関連記事
- nginxの基本的な設定ファイルの書き方
- nginx 502 Bad Gatewayエラーの原因と解決方法
- nginxのlocationディレクティブの書き方と優先順位
- nginxのリバースプロキシ設定(Node.jsアプリをnginxで公開する)
- Linuxのファイルパーミッション(chmod/chown)完全ガイド
この記事は errsolved.com にも掲載しています。