[Sy] nginx + php-fpm の環境で 500 エラー (Internal Server Error) が起きた場合の2つの調べ方
nginx + php-fpm の環境で 500 エラーが起きた場合、php.ini の設定( display_errors = Off の場合)によってはちょっと原因が見えにくかったりします。その場合の調べ方について説明します。
500 エラーが発生。何が起きてるのか?
そもそも HTTPレスポンスコードが500の場合、これは Internal Server Error(内部サーバーエラー) というものになります。
すべてがそうではないですが、PHPを扱っている場合にこれが起きる場合、 PHPの構文エラー(Syntax Error)の可能性があります。
ということで、まずは調べ方を2つ説明します。
調べ方
調べ方は、以下の2つの方法があります。
- 1.
php.ini
のdisplay_errors
をOn
にする - 2.
php-fpm
の エラーログを確認する(本番環境ではこちらを推奨)
では細かく見ていきます。
1. php.ini の display_errors を On にする
まず1つ目の方法。
PHP の初期設定では、エラーが起きた場合に ブラウザ上にエラーメッセージが表示されないようになっています 。
chromeだとこんな感じになります。
これじゃ、ちょっとどう調べてよいかさっぱりです。
それも当然。
エラーの手がかりとなる情報をむやみに外に出してしまうと、悪意のある人に攻撃のヒントを与えてしまうことになりかねません。 自分にわかりやすくするということは、一方で他人にもわかりやすくなりますよね。
この「エラーに関する情報を見えるようにするかどうか」を php.ini
にある display_errors
という設定項目で切り替えられるようになっています。
デフォルトだとこれが Off
になっているので、これを On
にしてあげるというのが、一つ目の方法です。
ただし、先程書いたように、 本番環境でこの設定を On
にすることは控えましょう。
開発用の環境であれば、エラーがブラウザ上からすぐにわかるので、デバッグのしやすさを考えると便利です。
では設定を変更してみます。php.ini
を vim
などで開いて編集します。
$ sudo vim /etc/php.ini
以下の行を書き換えて、
display_errors = Off
↓
display_errors = On
php-fpm
を再起動します。
$ sudo service php-fpm restart
やることは以上です。
もう一度問題のURLにアクセスすると、エラーメッセージが確認できるようになってるはずです。(エラー内容はエラーによって変わります)
この例だと、どうやら index.php
の1行目でおかしなところに :
が打たれてしまってるようです。
index.php
を確認してみると、
<?php phpinfo(): <- 最後がセミコロンではなくコロンになってしまっている!
はい、原因がわかりました。
このようにエラーメッセージをブラウザ上に表示させることで、それが大事な手がかりとなって簡単に解決できる場合がほとんどです。
さっそく修正してみると、無事に phpinfo()
の実行画面が表示されました。
ついでに、先ほどいじった display_errors
の設定値が確認できるので見てみると、 On
になってるのがわかります。
これが Off
の場合(デフォルト)では、こうなってます。
2. php-fpm の エラーログを確認する(本番環境ではこちらを推奨)
続いて2つ目です。こちらはサーバー上でのコマンド操作のみになるので、 外部にエラー内容を見せたくない場合に使えます。
nginx
と php-fpm
の環境だと、それぞれでエラーログが出力されていますが、 PHPの構文エラーの場合は php-fpm
のログを確認する必要があります。
以下のコマンドを打ちます。php-fpm
のバージョンによって、バージョンの数字の部分は異なります。
(/var/log/
配下は root
の持ち物なので、sudo su
で root
に切り替えてます)
$ sudo su
# cd /var/log/php-fpm/7.0/
# ls
error.log www-error.log
www-error.log
の中身を見てみると、
# cat www-error.log
[11-Oct-2017 07:52:15 UTC] PHP Parse error: syntax error, unexpected ':' in /var/www/test/index.php on line 1
と、ログを見ることで 先ほどブラウザ上に表示されていたエラーメッセージとまったく同じ内容が確認できることがわかります。
2つ目の調べ方は以上です。
ちなみに、 この時の nginx
のエラーログ /var/log/nginx/error.log
には特に何も出力されません。
そこでアクセスログ /var/log/nginx/access.log
を見てみると、
xxx.xxx.xxx.xxx - - [11/Oct/2017:07:52:15 +0000] "GET / HTTP/1.1" 500 5 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36" "-"
というログが確認できます。途中にある 500
というのが HTTPレスポンスコードになるので、何かしらエラーが起きたということはわかりますが、それ以上の情報は得られません。
ひとこと
環境に応じて対処のしかたを変えると良いですね。
また、レスポンスコードによっては、nginx
のエラーログを見る必要が有る場合もあるので、まぁとにかくエラーが起きたらどちらのログもチェックすると良いのではないかと。どのようにアクセスを捌いているのか勉強にもなりますし。