composerメモリ不足エラーの対処法

PHPのパッケージマネージャーであるcomposerは多くのアプリケーションやPHPフレームワークの前提ツールとして普及していますが、往々にしてメモリ不足でエラー終了します。

依存関係を解決するためにcomposerが大量のメモリを必要とするからです。 Composer update runs but out of memory(github.com/composer)でオフィシャルに議論されている内容が実態をよく表しています。2013年5月から3年近く活発に投稿が続いた結果、依存のパース処理に関する改善提案なく本質的に未解決のまま単にクローズ、という経緯をたどっています。

composerがメモリ不足で実行できない問題への対処は物理的にメモリを追加するしかありません。メモリ拡張手段は、スワップの追加(OSがRAMとして扱える)でも構いません。

メモリ不足の環境では、phpのオプションでメモリ使用の上限をセットしてもstatus 137で異常終了しますし、他にもOOM killerに止められる(dmesgコマンドで確認できます)、kubernetesコンテナ環境ではEviction Managerによってpodごと止められevictedステータスになる、といった形で見ための違いこそあれど、要するにOOMにヒットします。

kubernetes環境のcomposerの通し方

ベアメタルサーバーの場合は、既述のとおりスワップ追加による対処が確実でしょう。

しかし、GKEやkubernetes環境ではスワップなしの構成が前提となっているため、実行環境を別途用意するしかありません。

ビルド時にcomposerを実行する手順であればビルド環境を増強する必要がありますし、プロダクション増強が必要な構成もあるでしょう。

メモリを大量に消費するのは主にcomposer実行時に限られることから、kubernetes環境では一時的に別ノードプールを用意してcomposerを流すプロセスだけメモリ確保する手も有効です。ただし、composerの実行結果がpersistentDiskなどに保持できる前提です。

GKEではプリエンプティブVMを利用するとより安価に実行できます。ノードプールを指定してpod作成する手順については、 kubernetesのnode運用の具体例で解説しています。

まとめ:PHP = composerはコンテナ環境に難あり

コンテナ環境のリソース管理では、メモリの必要量が劇的に変動しないことが暗黙の前提となっており、実行時よりも大きなメモリを必要としがちなcomposerは運用のネックになります。

開発環境や利用パッケージにPHPベースのプロダクトを採用する場合には、メンテナンスの手順もあらかじめ整備・検証しておくべきでしょう。

中馬崇尋
Chuma Takahiro