この記事について
| 環境 | Laravel + Apache(RHEL系)、本番/ステージング構成 |
|---|---|
| 目的 | ステージングでは正常なのに本番だけ500エラーになる原因を特定して復旧する |
| 結果 | 古い構造のキャッシュが本番にだけ残っていたのが原因。キャッシュキー変更で即効復旧し、cache:clear を阻んでいた権限問題を修正して本質解決 |
つまずきポイント要約
- 本番だけキャッシュTTLを12時間にしていたため、古い構造のデータが本番にだけ残った
- Bladeの
?? ''は500を止める応急処置にはなるが根本解決ではない - キャッシュキーにバージョン(
v2:)を付けると、古いキャッシュを即座に無視できる php artisan cache:clearが権限エラーで失敗するときはstorage/bootstrap/cacheのグループ・setgid・ACLを見直す
事象
ステージングでは正常に表示されるが、本番環境だけ500エラーになる
ログを見ると:
production.ERROR: Undefined array key "code"
production.ERROR: Undefined array key "word_url"
production.ERROR: Undefined array key "favorite_prefix"
Bladeで $tile['code'] などが存在しないと怒られている
原因
キャッシュの中身が古いままで、本番環境だけ更新されなかった。
$ttl = app()->isProduction() ? now()->addHours(12) : now()->addSeconds(1);
本番のみ12時間キャッシュが古いまま残る設定にしていた。
問題の箇所:
$table1Sections = Cache::remember("word_table1_sections:{$languageColumn}:{$wordUrlNo}", $ttl, function () {
// buildWordTiles() の結果をキャッシュ
});
ここでキャッシュされる $tile が古い構造のデータだった。中に入るべき変数が不足してエラーが起こった。
対処
① 応急処置
Bladeでエラー回避:
:code="$tile['code'] ?? ''"
:word-url="$tile['word_url'] ?? ''"
:favorite-prefix="$tile['favorite_prefix'] ?? ''"
500エラーは止まるが、根本解決ではない
② キャッシュキーを変更(即効復旧)
Cache::remember("v2:word_table1_sections:...", ...)
古いキャッシュを無視できる
③ 権限の修正(本質対応)
キャッシュを削除すればいいだけのことだ、今回キャッシュが削除できずに苦労した。
$ php artisan cache:clear
ERROR Failed to clear cache. Make sure you have the appropriate permissions.
グループにapache追加
sudo usermod -aG apache ユーザー名
権限修正
sudo chgrp -R apache storage bootstrap/cache
sudo chmod -R 775 storage bootstrap/cache
setgid設定
sudo find storage bootstrap/cache -type d -exec chmod 2775 {} \;
ACL設定
sudo setfacl -R -m g:apache:rwx storage bootstrap/cache
sudo setfacl -R -d -m g:apache:rwx storage bootstrap/cache
確認
php artisan cache:clear
INFO Application cache cleared successfully.
復旧。
