LoginSignup
2

More than 1 year has passed since last update.

[AWS EC2]nginxとphp-fpm周りでエラーが発生した場合の解決策

Posted at

はじめに

この記事はプログラミング初学者による備忘録用の記事であり、また、少しでも他の初学者のお役に立てればと思い書いています。

今回は、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の設定を再確認して下さい。

スクリーンショット 2022-03-02 17.21.22.png

2./etc/php-fpm.d/www.confの実行ユーザーを確認

Laravelアプリケーションを動かす際は、権限絡みで問題が発生しないようにプールのユーザーとグループを実行ユーザーに変更しておく必要があります。

動かしたいLaravelアプリケーションを、EC2インスタンス上のどの実行ユーザーのホームディレクトリ配下にインストールしたかを確認し、状況に合わせて/etc/php-fpm.d/www.confのユーザーとグループをEC2インスタンスの実行ユーザー名に変更します。

/etc/php-fpm.d/www.conf
# 略

; 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の通信方法の設定を確認

TCPUNIXドメインソケットのどちらで通信しているかを確認しておく必要があります。
php-fpm側の設定では、/etc/php-fpm.d/www.confのlistenディレクティブで通信方法が定義されており、TCPUNIXドメインソケットを確認して、パスの内容を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

/etc/php-fpm.d/www.conf
; 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を指定します。

/etc/nginx/nginx.conf
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と接続できる状態になります。

/etc/php-fpm.d/www.conf
; 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.ownerlisten.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;と指定する必要があります。

/etc/nginx/nginx.conf
# 略
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)

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2