はじめに
この記事はプログラミング初学者による備忘録用の記事であり、また、少しでも他の初学者のお役に立てればと思い書いています。
今回は、EC2×Nginx×php-fpm×Laravelで開発中に、ブラウザ上でhttp://EC2インスタンスのパブリックIPアドレス/login
に接続後、ログイン画面の表示に成功したものの、ユーザー登録を実行した際に、404 Not Foundと表示され非常に悩まされたので、解決に至るまでに試したことを記録しておきたいと思います。
間違いなどがございましたら、ご指摘のほどよろしくお願い致します。
エラー内容
ブラウザ上で、http://EC2インスタンスのパブリックIPアドレス/login
に接続後、Laravelアプリケーションのログイン画面の表示に成功したものの、ユーザー登録を実行した際に404 Not Found
が表示されユーザー登録に失敗した。
今後、同様のエラーに悩まされないよう、解決するまでに試したことを記録しておきたいと思います。
1.php-fpmとnginxの接続を確認
ドキュメントルート/usr/share/nginx/html/
にphpinfo.phpのテストファイルを追加して、PHP Versionに関する詳細画面が表示されるかどうかを試す。
下記のコマンドを実行して、ドキュメントルートでphpが実行できるかを確認します。
# ec2-userでphpinfo.phpをvi起動で作成
[ec2-user@ip-###-##-##-## ~]$ sudo vi /usr/share/nginx/html/phpinfo.php
# vi起動後、/usr/share/nginx/html/phpinfo.php上で下記のコードを入力、保存
<?php phpinfo(); ?>
ブラウザでhttp://EC2のパブリックIPアドレス/phpinfo.php
に接続
接続後、PHPVersionの詳細画面が表示されれば、php-fpmとnginxの接続は成功です。
エラーが起きた際は、/etc/nginx/nginx.conf
と/etc/php-fpm.d/www.conf
の設定を再確認して下さい。
2./etc/php-fpm.d/www.conf
の実行ユーザーを確認
Laravelアプリケーションを動かす際は、権限絡みで問題が発生しないようにプールのユーザーとグループを実行ユーザーに変更しておく必要があります。
動かしたいLaravelアプリケーションを、EC2インスタンス上のどの実行ユーザーのホームディレクトリ配下にインストールしたかを確認し、状況に合わせて/etc/php-fpm.d/www.confのユーザーとグループ
をEC2インスタンスの実行ユーザー名に変更します。
# 略
; Unix user/group of processes
; Note: The user is mandatory. If the group is not set, the default user's group
; will be used.
; RPM: apache user chosen to provide access to the same directories as httpd
user = 実行ユーザー名(nginx) ; #========この行をapacheから実行ユーザー名に変更します
; RPM: Keep a group allowed to write in log dir.
group = 実行ユーザー名(nginx) ; #========この行をapacheから実行ユーザー名に変更します
3.php-fpmとnginxの通信方法の設定を確認
TCPかUNIXドメインソケットのどちらで通信しているかを確認しておく必要があります。
php-fpm側の設定では、/etc/php-fpm.d/www.confのlistenディレクティブ
で通信方法が定義されており、TCPかUNIXドメインソケットを確認して、パスの内容をnginx.confファイルのfastcgi_pass
と合わせる必要があります。
下記のように、UNIXドメインソケットを利用したlisten = /run/php-fpm/www.sock
であれば、nginx.confファイルのfastcgi_pass
にはunix:/run/php-fpm/www.sock
と指定する必要があります。
※TCPの場合はlisten = 127.0.0.1:9000
; The address on which to accept FastCGI requests.
; Valid syntaxes are:
; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific IPv4 address on
; a specific port;
; '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on
; a specific port;
; 'port' - to listen on a TCP socket to all addresses
; (IPv6 and IPv4-mapped) on a specific port;
; '/path/to/unix/socket' - to listen on a unix socket.
; Note: This value is mandatory.
listen = /run/php-fpm/www.sock #=======TCPかUNIXドメインソケットを確認する
UNIXドメインソケットの場合、下記のようにnginx.confファイルのfastcgi_pass
にはunix:/run/php-fpm/www.sock
を指定します。
location ~ \.php$ {
fastcgi_pass unix:/run/php-fpm/www.sock;
# 略
}
4./etc/php-fpm.d/www.conf
のlisten.ownerなどを変更しているかを確認する
php-fpmとnginxの通信方法で、UNIXドメインソケットを使用する場合はlisten.owner
などを変更する必要があり、変更していない場合、php-fpm.sockのパーミッションはnginxが読めない状態になります。
下記のように変更することで、php-fpm.sock の所有ユーザ・グループが変更されてnginxと接続できる状態になります。
; Set permissions for unix socket, if one is used. In Linux, read/write
; permissions must be set in order to allow connections from a web server.
; Default Values: user and group are set as the running user
; mode is set to 0660
listen.owner = ユーザー名(nginx) #=====セミコロン(;)を消して実行ユーザー名(nginx)に変更します
listen.group = ユーザー名(nginx) #=====セミコロン(;)を消して実行ユーザー名(nginx)に変更します
listen.mode = 0660 #=====セミコロン(;)を消します
補足
listen.ownerとlisten.groupでは、UNIXドメインソケットを利用する場合、ソケットのオーナー/グループを指定します。
Webサーバーからリクエストを受け付けるには、Webサーバーがソケットに対して読み書き可能な状態が必要とされます。
5./etc/nginx/nginx.conf
の設定を確認
ここでは、主にphp-fpmとの連携で重要な箇所を確認していきます。
確認すべき箇所は下記の通りです。
・root:ドキュメントルートの指定が間違っていないかを確認する。
・location:求められているlocation / {処理}
が設定できているかを確認する。
下記のtry_files $uri $uri/ /index.php?$query_string;
の処理内容は、
・リクエストされたURIにファイルが存在するかを確認($uri
の部分)
・ファイルが無ければ、リクエストされたURIにディレクトリが存在するかを確認($uri/
の部分)
・ディレクトリが存在しなければ、index.phpに内部リダイレクトする(/index.php?$query_stringの部分)
となっています。
・location ~ .php$:拡張子がphpであるファイルに対して行う処理を確認します。
・location内にrootパラメータを記述していないかを確認する。
・fastcgi_passが正しく指定されているかを確認する。UNIXドメインソケットの場合、unix:/run/php-fpm/www.sock
またはunix:/var/run/php-fpm/www.sock
を指定しているかを確認する。TCPの場合はfastcgi_pass= 127.0.0.1:9000
と指定する。
・fastcgi_paramが正しく指定されているかを確認する。index.php
をドキュメントルートに設置するのであれば、SCRIPT_FILENAME $document_root$fastcgi_script_name;
と指定する必要があります。
# 略
root /home/実行ユーザー名/特定のディレクトリ/public;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass unix:/run/php-fpm/www.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
終わりに
私の場合、上記5つを試したところ、/etc/php-fpm.d/www.conf
のlistenの値と/etc/nginx/nginx.conf
のfastcgi_passの値が一致していなかった為、エラーが発生していました。
この記事が少しでもお役に立てれば嬉しいです。
参考文献
nginx docs
Laravel 6.x デプロイ
PHP docs FastCGI Process Manager (FPM)