結論
bootstrap/cache/config.php
に保持してる暗号化キーの項目にenvのAPP_KEY
の値が反映されていなかった。
(キャッシュが更新されていなかった)
php artisan config:cache
でキャッシュを更新することでエラーを解消。
何が起きたか
社内のLaravelアプリのバージョンを5.7→8系に上げている作業中に事は起きた。
細かい動作確認は後で行うつもりでとりあえずLaravelが8系で動くように更新。
雰囲気で動作しているのを確認した後に、公式謹製のDockerライブラリであるSailをインストールして、動作確認をしていた。
Composer経由で無事にインストールが済んだので sail up -d
でコンテナを立ち上げ画面を確認してみた。
「No application encryption key has been specified.」だと?嘘だろ?
このエラーはenvファイルのAPP_KEYに値が設定されていない時によく見るエラーだ。
そんな初歩的なミスをする理由がないと思い、envファイルを確認してみた。
しっかり値が入っている。
なにかの間違いかと思い、ブラウザのキャッシュを消しもう一度アクセスしてみる。
エラーはまだ表示されている。
なぜだ?ワケがわからないよ。。。
Laravelがenvファイルを読み込めていない可能性を考え、tinkerでAPP_KEYの値を読み込んでみる。
なんならconfigからも値を確認してみる。
envファイルからもconfigからもちゃんと値が取れている。
なのに画面上ではキーが無いと怒られている。
どうしてだ。なぜなんだ。。
腑に落ちない思いをしながらも色んな記事を漁る。
するとLaravelのキャッシュに関する、ある記事を見つけた。
記事内にある下記のコマンドを実行してみる。
composer dump-autoload
php artisan clear-compiled
php artisan optimize
php artisan config:cache
Laravel キャッシュクリア系コマンドなど
の「ちょっと踏み込んだキャッシュクリアコマンド」より引用
なんとエラーが解消された!!!
と、同時に今回のエラーの原因がLaravelのキャッシュにあることが分かった。
解説してみる
タイトルの現象が発生していた真の原因とは?
エラーが発生していた時点では、envからAPP_KEYは確かに読み込めていた。
しかし、Laravel上で保持しているキャッシュを参照してしまっていたかつ、キャッシュ上のキーには値が設定されていなかった為エラーが発生していた、という訳だ。
具体的には、bootstrap/cache/config.php
にLaravelのキャッシュを保持していてその中の app.key
にブランクが設定されていたのだ。
↓の画像はキャッシュが正しく設定された状態の bootstrap/cache/config.php
キャッシュの理解度が甘かった自分の所為でもあるのだが、これに気づくのが結構難しかった。
キャッシュの更新方法
ところで、参考にした記事のコマンドを実行して解決には至ったものの、そのコマンドで何が行われていたのかをしっかり抑えて置かなければならない。
php artisan config:cache
特にこれ。
使ったことはあるけど、イマイチ理解してなかった。
「あーキャッシュしてくれるんでしょ?configを」
といった程度の雑な理解度。
コマンド実行後のファイル(bootstrap/cache/config.php
) を見てみると全貌が見えてくる。
ただ配列が定義され、それがreturnされているだけのファイルだが、よく見ると、
- app
- auth
- broadcasting
- cache
- database
のように既視感のある名称がキーになっている。
そう、これはconfig配下に配置された各種configファイルを1つにまとめたファイルだったのだ。
ここにピンと来れば、配列内部の構造の意味もわかるし、Laravelがconfigファイルをどの様にキャッシュに持たせているのかも理解できる。
つまり php artisan config:cache
コマンドは、configディレクトリ配下に定義されたconfigファイル達を bootstrap/cache/config.php
ファイルに1つの配列として定義する処理が行われていたのだ。
おわりに
今後、envファイル関連のエラーに遭遇した場合は、envファイルだけでなくキャッシュファイルも併せて確認することを肝に銘じた。