先日、学習用で構築したawsでprotectedサブネット内にあるEC2にWebサーバー(Apache)、PHP実行環境(PHP-FPM)、データベース(MySQL)を置き、ALBによってインターネット上からアクセスできるようにしてみました。
しかし、Application Load Balancer (ALB) のターゲットグループのヘルステータスが 500 エラーで失敗し続けるという事象が発生。
この際の問題の切り分けと解消策について記録します。
発生した事象
ALBターゲットグループのヘルステータスが「Unhealthy」になり、原因コードに「Health checks failed with these codes: [500]」と表示。
(エラー時のキャプチャ取り忘れました…)

※赤枠部分の「ヘルスステータス」に「Unhealthy」、「ヘルスステータスの詳細」に「Health checks failed with these codes: [500]」と表示されていました。
原因特定までの流れ
1.アクセスログでエラーの発生源を特定
ALBは 500 を受け取ったことしか教えてくれないので、詳細を知るために踏み台サーバー経由で対象のEC2にSSH接続し、Apache Webサーバーへのアクセスログを確認しました。
tail -f /var/log/httpd/access_log
"GET / HTTP/1.1" 500 2431 "-" "ELB-HealthChecker/2.0"
ここで判明したこと:ELB-HealthChecker/2.0 からのルートパス (/) へのリクエストに対し、ターゲット(EC2)側が「500 Internal Server Error」を返していることが確認できました。
つまり問題はALBではなく、EC2インスタンス上のアプリケーションにあるといえそうです。
2.EC2上のWebサーバー/アプリケーションログの確認
Webサーバーのエラーログを確認し、アプリケーションのエラーを特定します。
・Apacheエラーログの確認
/var/log/httpd/error_log
結果:サーバーの正常起動通知のみ。アプリケーションの異常を示すログなし。
つまりApache自体が原因ではなさそう。
・PHP-FPMエラーログの確認
/var/log/php-fpm/error.log
結果:プロセスの再起動通知のみ。アプリケーションの異常を示すログなし。
つまりPHP-FPMプロセス自体の問題でもなさそう。
上記の通りログにエラーが出なかったのですが、ここでPHP環境ではエラーの出力を画面上に行う(display_errors)という設定があることを知りました。
3.画面に表示されたエラーの確認
EC2インスタンスの内部からアプリケーションに直接アクセスし、レスポンスボディ全体を確認しました。
[ec2-user@hogehoge html]$ curl http://localhost/
結果、以下のHTMLが出力
<title>Database Error</title>
...
<div class="wp-die-message"><h1>Error establishing a database connection</h1></div>
上記の結果から、HTTP 500エラーの正体は、PHPアプリケーション(WordPress)がデータベースへの接続を確立できないために発生していた可能性が高いことが分かりました。
(多分これはブラウザからでも確認できたはず)
4.データベース接続設定の確認
原因がデータベース接続にあるかもしれないため、データベースの設定ファイル(wp-config.php)を確認。
define( 'DB_USER', 'wordpress' );
define( 'DB_PASSWORD', 'password1234' );
この情報を利用し、EC2内で直接wordpressユーザーがMySQLに接続をができるか試します。
[ec2-user@hogehoge html]$ mysql -u wordpress -p
パスワードを聞かれるのでパスワード(password1234)を入力します。
ERROR 1045 (28000): Access denied for user 'wordpress'@'localhost' (using password: YES)
エラーの内容としては、wp-config.php に設定されているパスワードと、MySQLサーバーに登録されている wordpress ユーザーのパスワードが一致していないとのことでした…
解決策
正しいパスワードが何か覚えていないのでMySQLに管理者権限で接続し、パスワードをリセットする。
[ec2-user@hogehoge html]$ sudo mysql -u root -p //管理者権限で接続
Enter password: //管理者のパスワード
mysql> ALTER USER 'wordpress'@'localhost' IDENTIFIED BY 'piyopiyo1234'; //wordpressのパスワードを変更
Query OK, 0 rows affected (0.01 sec)
mysql> FLUSH PRIVILEGES; //変更を反映
Query OK, 0 rows affected (0.01 sec)
DB_PASSWORD の値を、MySQL側で設定した正しいパスワードに一致するようにwp-config.php を修正。
/** Database username */
define( 'DB_USER', 'wordpress' );
/** Database password */
define( 'DB_PASSWORD', 'piyopiyo1234' ); //変更
最終確認
パスワード修正後、再度 curl で確認。
[ec2-user@hogehoge html]$ curl -I http://localhost/
HTTP/1.1 200 OK
「Database Error」が解消され、「200 OK」が返されるようになりました。
その後すぐにターゲットグループのヘルステータスは Healthy に戻りました。
まとめ
ALBのエラー表示だけでは問題の詳細が不明なため、切り分けを行うのが必要だと分かりました。
