nginx + Laravel でホーム以外のページの404エラー解決

はじめに

前回はnginx + MySQL + Laravelの環境構築をしてトップページの表示まで行いました。さて、もりもり開発始めるぞー!と思った
が矢先、、
ログイン認証してみようと思ったら404エラー。なんでや、、と頭を抱えました。ルーティングに何もおかしいところはないし、どうしたものか、と思ったのですが原因はlaravel側ではなくnginxの設定だったようです。記事書いた時にnginxわかんないなぁ〜って放置したのはダメだったようです。わからないとこはちゃんと潰しておこう。。。。

修正前の元のファイル

さて、元のnginxのファイルであるdefault.confを見てみます。


default.conf

server {

listen 80;
index index.php index.html;
root /var/www/beer/public/;

location / {
root /var/www//beer/public;
index index.html index.php;
}

location ~ \.php$ {

try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}


結論から言ってしまうとこれダメダメすぎますね。数日前の自分が恥ずかしい。

記述の意味の理解と修正

まず、このファイルをディレクティブごとに読み解いていきます。

listen 80;

index index.php index.html;
root /var/www/beer/public/;

ここではサーバーのIPアドレスとポート番号を宣言し、そのあとに公開するディレクトリを宣言しています。

IPアドレスとポート番号は、listen IPアドレス:ポート番号のように書きます。

しかし今回はIPアドレスが記載されていませんよね。この書き方は、listen *:ポート番号と同じ意味を表しており、IPアドレスにはデフォルト値が用いられることになります。

root /var/www/beer/public/;は公開するディレクトリの宣言、

index index.php index.html;はリクエストuriが/で終わっている時にインデックスとして返されるファイルを表しています。index.phpが存在すればindex.phpを返し、存在しなければindex.htmlを返します。どちらも存在しない場合のリダイレクト先を設定したい場合は、index index.php index.html /ファイルがどちらもない場合のリダイレクト先;のようにします。

locationディレクティブ

location / {

root /var/www/beer/public;
index index.html index.php;
}

さて、問題はここにありました。まずはこのlocationディレクティブについてです。

locationディレクティブではuriのパスごとの設定を記述することができます。つまりこれは、「ホスト名/ にアクセスしたら、/var/www/beer/public と言うファイルパスを返す」と言う意味になります。

rootは先ほど宣言しているものと同じ公開ディレクトリのため、宣言する必要がないので消します。また、ここでindexを指定してしまうとこの二つのファイルしか開かないという設定になってしまうので修正します。そこで、

location / {

try_files $uri $uri/ /index.php?$query_string;
}

とします。これは、「ホスト名/ にアクセスしたら、まずリクエストURIで処理、次にindex.phpで処理を試みる」という意味です。こうすることで全てのURIに対応できます。

locationディレクティブその2

location ~ \.php$ {

try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}

try_files $uri =404;なんて記述のせいでindexの指定ファイルがなかったら404返されてたんですね。アホらしいです。大反省です。消します。

残りの行ですが、これはphpの処理を行うのに必要な記述だそうです。ここの解説はまた今度(まだよくわからない)

最終的にdefault.confはこんな感じになります。


default.conf

server {

listen 80;
root /var/www//beer/public;
index index.html index.php;

location / {
try_files $uri $uri/ /index.php?$query_string;
}

location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}


最後に

nginxは奥が深い。

ディレクティブの修飾子とか優先順位とかについても今度書きたいな。

参考文献

nginx実践入門

https://www.amazon.co.jp/nginx%E5%AE%9F%E8%B7%B5%E5%85%A5%E9%96%80-WEB-DB-PRESS-plus/dp/4774178667