目次
問題は解決したはずなのに500エラーが出る
JSON.stringifyが空要素をNULLに変換するようになってハマる
この問題が解決されてプログラム的に動くようにしたはずなのに翌日になったらまた500エラーを出すようになりました。なんでなんだろうなと思って調べてみたら、それほど重大ではない(既に登録済みだったから新規登録はしなかったよ、程度の)エラーログが出力されており、そのログをログファイルに書き込む過程で失敗していることがわかりました。道理でエラーログにエラーがないわけだ。
よくよく見てみるとログディレクトリはこんな感じになってました(抜粋)。
$ ls -al storage/logs
total 2548
-rw-rw-r-- 1 ec2-user apache 208778 Feb 20 23:45 laravel-2023-02-20.log
-rw-rw-r-- 1 ec2-user apache 171624 Feb 21 23:45 laravel-2023-02-21.log
-rw-rw-r-- 1 ec2-user apache 171624 Feb 22 23:45 laravel-2023-02-22.log
-rw-r--r-- 1 apache apache 171624 Feb 23 23:45 laravel-2023-02-23.log
所有者が「ec2-user」になっているファイルが前日までにパーミッションを変更したログファイル。一方所有者が「apache」になっているファイルはバッチが自動的に生成したログファイルです。バッチが生成したログファイルは書き込み権限が「644」になっていて、Laravelの実行ユーザである「ec2-user」に書き込み権限がありません。それで書き込みが失敗してしまっていたんですね。
常套手段は、apacheとec2-userを同じグループに入れてファイルを664で生成
パーミッション「664」なら同じグループに属しているユーザーには書き込み権限があることになります。手順は以下の以下の通り。- apacheのコマンドでグループを生成、ユーザーを追加
- ログディレクトリを1のグループに属させる
- Laravelのconfigを設定
apacheのコマンドでグループを生成、ユーザーを追加
例えば「laravel」というグループを作成し「root」「apache」「ec2-user」の3ユーザーを所属させます。$ sudo groupadd laravel
$ sudo gpasswd -a root laravel
$ sudo gpasswd -a apache laravel
$ sudo gpasswd -a ec2-user laravel
ログディレクトリを1のグループに属させる
$ sudo chown -R :laravel ./storage/logs
Laravelのconfigを設定
Laravelのconfig/logging.phpで、ログファイルのパーミッションを設定することが出来ます。'daily' => [
'driver' => 'daily',
'path' => storage_path('logs/laravel.log'),
'level' => 'debug',
'days' => 14,
'permission' => 0664, // ← 追加
],
これで大丈夫!……あれ?
ダメなときはACLを設定しましょう
僕の環境ではこうなってました。再びログディレクトリ。$ ls -al storage/logs
total 2548
-rw-rw-r-- 1 ec2-user laravel 208778 Feb 20 23:45 laravel-2023-02-20.log
-rw-rw-r-- 1 ec2-user laravel 171624 Feb 21 23:45 laravel-2023-02-21.log
-rw-rw-r-- 1 ec2-user laravel 171624 Feb 22 23:45 laravel-2023-02-22.log
-rw-rw-r-- 1 ec2-user laravel 171624 Feb 23 23:45 laravel-2023-02-23.log
-rw-r--r-- 1 ec2-user laravel 171624 Feb 24 23:45 laravel-2023-02-24.log
グループは設定出来ているものの、パーミッションは相変わらず644でした。元がどういう設定だったか今となってはわかりませんが、configを上回る(恐らくApache側の)なんらかの設定によって新規に生成されるログファイルのパーミッションは644に制限されているようです。じゃあ、これを上書きしましょう。
というわけで、こう。
$ sudo setfacl -R -d -m g:laravel:rwx ./storage/logs
これを実行すると、ACLが追加されます。確認してみるとこんな感じ。
$ getfacl storage/logs
# file: storage/logs
# owner: ec2-user
# group: laravel
# flags: -s-
user::rwx
group::rwx
other::r-x
default:user::rwx
default:group::rwx
default:group:laravel:rwx
default:mask::rwx
default:other::r-x
「default」以下が追加されたルールで、「default:group:laravel:rwx」はlaravelグループのユーザーに書き込み権限を与えることを示しています。これで解決。
ちなみに:ACLを削除するときは
このコマンドでOKらしいです。$ sudo setfacl -b ./storage/logs
しかしこれは僕の個人サーバだから適当でも構わないですけど、実際の場面では個別のディレクトリに個別のアクセスコントロールを設定するのは運用上問題があるよなあと思います。きちんとApacheの設定を見てしかるべきセキュリティ設定をすべきじゃないのかと思ったんですけど、残念ながらそこまではわかりませんでした。どうするのが完全に正解なのかな?