🎻
symfony/monolog-bundleを入れているプロジェクトがプロダクション環境で動かなかった話
僕がSymfonyプロジェクトを作るときに毎回使っている ttskch/symfony-micro-skeleton というイカしたスケルトンがあるんですが、これを使って作ったプロジェクトをHerokuにデプロイしたら
PHP Fatal error: Uncaught Error: Class 'Symfony\Component\Console\ConsoleEvents' not found in /path/to/vendor/symfony/monolog-bridge/Handler/ConsoleHandler.php:139
というエラーになってしまいました。原因と解決方法などをメモに残しておきます。
そもそもHerokuでSymfonyを動かすときの注意点
HerokuでPHPプロジェクトがビルドされる際に実行されるコマンドは
composer install --no-dev --prefer-dist --optimize-autoloader --no-interaction
となっていて、 --no-dev
が付いているので require-dev
で依存しているライブラリはインストールされません。(公式情報)
なので、Symfonyプロジェクトをホストする場合は、環境変数に APP_ENV=prod
を明示的にセットしておかないと、 require-dev
なクラスが色々とNot foundになってしまって動作しません。
symfony/monolog-bundleの罠?
今回起こったのは、
- symfony/monolog-bundleがインストールされていて
- Symfony Recipeによってインストールされた デフォルトの
prod/monolog.yaml
が配置されているプロジェクトを - Herokuにデプロイして
APP_ENV=prod
をセットしたら -
PHP Fatal error: Uncaught Error: Class 'Symfony\Component\Console\ConsoleEvents' not found in /path/to/vendor/symfony/monolog-bridge/Handler/ConsoleHandler.php:139
になった
ということです。
コードを追ってみると、
- デフォルトの
prod/monolog.yaml
でconsole
ハンドラーが使われている - そして、symfony/monolog-bridgeの
ConsoleHandler
クラスは、symfony/consoleの各種クラスに依存している - しかし、symfony/monolog-bundleはsymfony/consoleに
require-dev
でしか依存していない - なので、symfony/monolog-bundleをrequireしただけのアプリだと、
composer install --no-dev
かつAPP_ENV=prod
の環境においてsymfony/consoleの各種クラスがNot foundになってしまう
という状況のようでした🤔
デフォルトの prod/monolog.yaml
で console
ハンドラーが使われていることが間違いな気がするので、とりあえずsymfony/recipesにissueを立ててみました。反応を待ちます。
https://github.com/symfony/recipes/issues/752
解決策
当たり前ですが、以下のように config/packages/prod/monolog.yaml
で console
ハンドラーを使わないようにしておけばとりあえずエラーにはなりません。
# config/packages/prod/monolog.yaml
- console:
- type: console
- process_psr_3_messages: false
- channels: ["!event", "!doctrine"]
+ # console:
+ # type: console
+ # process_psr_3_messages: false
+ # channels: ["!event", "!doctrine"]
ttskch/symfony-micro-skeletonでもとりあえず同様の対処をしてあります。
本家のissueで何か別解が示されたらそれに合わせた対応をしようと思います。
まとめ
- symfony/monolog-bundleをインストール&レシピでmonolog.yamlを作成したままだと、
composer install --no-dev
かつAPP_ENV=prod
な環境で以下のエラーになったPHP Fatal error: Uncaught Error: Class 'Symfony\Component\Console\ConsoleEvents' not found in /path/to/vendor/symfony/monolog-bridge/Handler/ConsoleHandler.php:139
- SymfonyアプリをHerokuでホストしている場合に起こりやすいのでお気をつけて
-
console
ハンドラーを使わないようにprod/monolog.yaml
を修正すればとりあえず直る - https://github.com/symfony/recipes/issues/752 の反応を待つ
Discussion