Home > アーカイブ > 2014-05
2014-05
Heroku で Composer を使う時に気を付けたいこと
Heroku が PHP をサポートしたので、テストがてら Laravel アプリケーションをデプロイしてみました。
デプロイしたのは、Doctrine を利用するアプリケーションだったのですが、ローカルでは composer でインストールできるのですが、Heroku にデプロイするとインストールされないという現象が起こりました。
Laravel での Doctrine 使用
今回のアプリケーションでは、DBのテーブルスキーマ情報を読み込んで、動的に画面を作るという処理があり、そこで Doctrine の SchemaManager を使っていました。
Laravel で、Doctrine の SchemaManager のインスタンスを取得するのは簡単で、下記のメソッドを実行するだけです。
$manager = DB::connection()->getDoctrineSchemaManager();
こんなあっさりなので、laravel/framework
パッケージをインストールすると、Doctrine も入るものだと思ってました。
Heroku での Composer
Heroku へデプロイするコードのルートディレクトリにcomposer.json
が含まれていると、PHPアプリケショーンとしてセットアップが行われます。(依存解決に Composer を使わない場合でも、空のcomposer.json
が必要です。)
このcomposer.json
では、通常の依存関係を指定するだけでなく、実行するPHPバージョンや拡張の指定ができます。例えば、下記のようにするとPHP 5.5.12
をランタイムにして、memcached
拡張が利用できます。
{ "require": { "php": "5.5.12" "ext-memcached": "*", } }
この記法は、Composer としてはサポートしているのですが、Composer 自身がランタイムの変更などを行うわけではありません。
そこで、Heroku の Composer は独自拡張しているのだろうと考えました。まあ、この思い込みが惑わすわけですが。
あと、Heroku での PHP サポートは、まだベータなので、そのせいもあるのかなと思ってました。
https://getcomposer.org/doc/02-libraries.md#platform-packages
開発環境、別 PaaS では正常に動作
もちろん開発環境(OSX, Linux VM)では、Heroku にデプロイしたものと同じコード(composer.(json|lock))で問題無く動いていました。
別のPaaSを試してみようと思い、Pagodabox に設置すると、これも正常に動作しました。
Heroku と 別 PaaS で、vendor/ 以下を比べると、10個近くのパッケージがHerokuでは入っていませんでした。
なぜ Heroku だけ入らない。やっぱり、独自拡張のせい?ベータ版だから?
–no-dev!
この作業していたのが、夜中でした。Pagodabox にデプロイできたので、これで良しとして、その日は寝ました。
しかし、気になるのが、同じ現象をググっても、Laravel アプリケショーンが Heroku で動かない,
Doctrine が入らないなんて出てこないんですね。動かしてみた系の記事はあるのに。
翌日、もう一度、Heroku の公式のドキュメントを読み直すことにしました。
すると、ありました。ちゃんと書いてありました。実行する composer コマンドが。
Heroku では、下記のオプション付きで実行するようです。そう、--no-dev
オプション付きでね!
$ composer install --no-dev --prefer-dist --optimize-autoloader --no-interaction
早速、手元で同じオプションで実行してみると、ちゃんとDoctrineがインストールされない。
ああ、これか。。。
Heroku PHP Support | Heroku Dev Center
–no-dev オプション
composer コマンドでは、いくつかオプションを指定することができ、--no-dev
はその一つです。
Composer公式サイトでは、下記の記述があります。--no-dev
オプションを付けると、依存解決する際にcomposer.json
のrequire-dev
セクションの内容は解決されません。
--no-dev: Skip installing packages listed in require-dev.
デフォルトでは、--dev
が付いているのと同じ状態になり、require-dev
セクションの内容も依存解決の対象となります。
https://getcomposer.org/doc/03-cli.md#install
依存パッケージのcomposer.jsonをチェック
アプリケーションが依存しているパッケージのcomposer.json
を洗い出してみると、require-dev
にDoctrineを指定しているものはいくつかあれど、require
に指定しているものは見事にありませんでした。
つまり、開発環境やPagodaboxでは、--no-dev
無しだったため、require-dev
セクションを含んで依存解決したため、Doctrine が入っていました。
かたや、Heroku では、--no-dev
ありだったので、Doctrine が入りませんでした。おそらく Heroku だけに入らなかった他のパッケージも同様でしょう。
[解決] require に doctrine を指定
はい、原因は分かったので、解決方法です。
composer.json
のrequire
に、Doctrine を追加しました。
"require": { "php": ">=5.4.0", "laravel/framework": "4.1.*", "doctrine/dbal": "~2.3" // <--- 追加! },
Heroku にデプロイすると、バッチリ動きました!Herokuさん、疑ってゴメン。
実際にデプロイしたものが下記です。
http://laravel-table-admin.herokuapp.com/crud/classes
コードは、Github で公開しています。Heroku でも Pagodabox でもデプロイできているので、両 PaaS にPHPアプリケーションをデプロイする際は参考にどうぞ。
https://github.com/shin1x1/laravel-table-admin-example
さいごに
まあ分かってしまえば、単純というよくある話です。
Heroku が Composer を拡張しているかどうかは分かりませんが、ドキュメントには、composer 実行前に self-update しているという記述もあるので、Composer は標準のもので、別途compoer.json
を見てランタイムを決定するシステムがあるのかもしれません。
あと、夜中に躓いたら、さっさと寝るということですね。睡眠大事。
追記
”別途compoer.jsonを見てランタイムを決定するシステム”は多分この辺だと思う https://t.co/t5qXCkwKuH Heroku で Composer を使う時に気を付けたいこと http://t.co/vJRlTTV5Q6 @shin1x1さんから
— ISHIDA Akio (@iakio) 2014, 5月 26
ラインタイムや拡張を実際に指定する処理は、PHP の buildpack に記述がありました。@iakio さん、ありがとうございました!
- ラインタイムの決定(PHPバージョン or HHVM)
https://github.com/heroku/heroku-buildpack-php/blob/master/bin/compile#L106-L133 - 有効にする拡張の決定
https://github.com/heroku/heroku-buildpack-php/blob/master/bin/compile#L185-L208
- コメント (Close): 0
- トラックバック (Close): 0
Home > アーカイブ > 2014-05
- 検索
- フィード
- メタ情報