【Laravel】バッチ処理が失敗し「ErrorException: file_put_contents(cache_dir) failed to open stream: No such file or directory」というエラーが残っていた

定期的に実行しているバッチがなぜか実行されておらず、調べたらこんなエラーログが残ってました



production.ERROR: ErrorException: file_put_contents(/var/www/laravel/storage/framework/cache/data/14/7d/147d15f9838dfr62e4cb69b9de6a831aecc9544d): failed to open stream: No such file or directory in /var/www/laravel/vendor/laravel/framework/src/Illuminate/Filesystem/Filesystem.php:122


キャッシュが書き込めない or 読み込めないというエラーなのですが、キャッシュディレクトリの設定は正しく行われているのでなぜこんなことになっているかわからない。検索して出てくる情報は「キャッシュの更新」ですが、それをやっても改善しなかったので調べてみたところどうもパーミッションが合っていなかった様子。



対症療法

根本的な解決にはなりませんが、キャッシュディレクトリのパーミッションを変更することで問題は回避できます。今回の場合、

  • cache/data/14 → 「apache」ユーザー「755」
  • cache/data/14/7d → 作成不可

ということだったので、該当ディレクトリのパーミッションを「777」に変更することで対処しました。だいぶ乱暴ですが。



根本的な原因

バッチの実行ユーザーはapacheの実行ユーザーである「ec2-user」のはずなんですけど、キャッシュディレクトリを見てみるとフォルダの作成ユーザーがところどころ「apache」になっているらしい。で、そのフォルダ直下にディレクトリを作ろうとすると失敗する……ということはわかったんですけど、ではどの処理が所有者「apache」ユーザーのキャッシュディレクトリを作っているのか?と思って見ていくとよく分からないんですよね。どこかでapacheがキャッシュファイルを作成しているんだと思うんですけど。


一応、laravel\vendor\laravel\framework\src\Illuminate\Cache\FileStore.php ではこんな感じになってて、キャッシュディレクトリは常に「777」で作られてPermission Deniedは発生しないはずなんですけど……どこかで別の設定しているのかな。


/**
* Create the file cache directory if necessary.
*
* @param  string  $path
* @return void
*/
protected function ensureCacheDirectoryExists($path)
{
   if (! $this->files->exists(dirname($path))) {
       $this->files->makeDirectory(dirname($path), 0777, true, true);
   }
}



根本的な原因がわからないままだとまたいずれ再発することになりますが、まあ仕方ないかな。もうちょっと調べてみます。または諦めるか。なかなかそういうわけには行きませんが、キャッシュディレクトリをあらかじめ作ってしまうという手もなくはないですね。これまたかなり乱暴ですが。