🎻

[PHP] Herokuへのデプロイでrequire-devの依存もインストールする

2020/05/18に公開約3,200字

課題

Heroku標準のPHP buildpack を使ってPHPのプロジェクトをデプロイする際、実行されるビルドコマンドは

$ composer install --no-dev --prefer-dist --optimize-autoloader --no-interaction

となっています。(参考

つまり、 require-dev で依存しているライブラリはインストールされません。

しかし、ステージング環境としてHerokuを使っている場合など、アプリのデバッグモードをONにするために require-dev の依存もインストールしたいことがあります。

例えばSymfonyなら、無造作にHerokuの環境変数で APP_ENVdev にしてしまうと、 require-dev で依存しているクラスが見つからず ClassNotFoundError になってしまいます。

解決策

強引な方法ですが、 composer install コマンドの実行後に

composer compile --no-dev --no-interaction

という カスタムコマンド が実行される仕様(参考)なので、ここで改めて require-dev の依存をインストールするようにしてあげれば解決できます。(完全に二度手間でまったく美しくないですが…)

# composer.json
{
    "scripts": {
        "compile": [
            "composer install --prefer-dist --optimize-autoloader --no-interaction",
        ]
    },
}

データベースのマイグレーションコマンドなんかもこの compile カスタムコマンド内で実行するのがセオリーですね。

{
    "scripts": {
        "compile": [
            "composer install --prefer-dist --optimize-autoloader --no-interaction",
            "php bin/console doctrine:migrations:migrate -n --no-debug"
        ]
    },
}

app.jsonscripts.postdeploy でもできる?

この辺を見る限り、composer.jsoncompile カスタムコマンドを使わずに app.json

{
    "scripts": {
        "postdeploy": "composer install --prefer-dist --optimize-autoloader --no-interaction && php bin/console doctrine:migrations:migrate -n --no-debug"
    }
}

みたいな内容で作っておくでも期待どおり動くのかもしれません。が、未確認ですごめんなさい🙏

ちなみに:Symfonyの場合の注意点

なお、先に挙げたSymfonyを APP_ENV=dev で動かしたいというケースでは、たとえこの方法で require-dev の依存をインストールするとしても、デプロイの時点で APP_ENV=dev をセットしてしまっていると ClassNotFoundError になります。

なぜなら、1回目の composer install --no-dev の直後に post-install-cmd フックで bin/console cache:clear などを実行するためにSymfonyが起動されてしまうからです。

なので、あくまで普段は APP_ENV=prod にしておいて、いざデバッグしたいときに APP_ENV=dev に変更してアクセスする、というような使い方になります。

これを回避するには、post-install-cmd@auto-scriptscache:clear などを含む)を --no-dev オプションが付いていない場合のみ実行するようにすればよいです。

具体的には以下のように COMPOSER_DEV_MODE 環境変数が 0 でない(= --no-dev が付いていない)場合にのみ composer auto-scripts によって @auto-scripts を実行するようにします。

  "post-install-cmd": [
-     "@auto-scripts"
+     "if [ $COMPOSER_DEV_MODE -ne 0 ]; then composer auto-scripts; fi"
  ]

参考:Symfony4.4をGAE/phpで動かす | polidog lab

まとめ

  • PHPプロジェクトをHerokuへデプロイする際にrequire-devの依存もインストールしたければ、 compile カスタムスクリプト内で改めて composer install してあげればよい(美しくはないけど)
GitHubで編集を提案

Discussion

ログインするとコメントできます