CI/CDでComposerをどう扱うべきか 実践的整理

CI/CDでComposerをどう扱うべきか、結論から言うと「Composerを開発者の便利ツールとして扱うか、それともビルド工程の一部として扱うかを最初に決め、その前提をCI/CD全体に一貫させること」が重要です。
この前提が曖昧なまま進めると、ローカルでは動くのにCIで失敗する、あるいは本番だけ不具合が出るといった、ありがちな事故に繋がりやすくなります。

この記事では、CI/CDとComposerの関係を整理しつつ、実際の現場でよく採られているパターン、そのメリット・デメリット、そして失敗しがちなポイントまで具体的に解説していきます。

CI/CDにおけるComposerの位置づけ

CI/CDとは、コードの変更を自動的にビルド・テスト・デプロイする仕組みです。
ComposerはPHPの依存関係を管理するツールなので、CI/CDの中では次のどこかに組み込まれます。

  • CIでComposer installを実行する
  • 事前に依存関係を解決し、成果物としてまとめる
  • CIではComposerを極力使わない

どれが正解という話ではなく、プロジェクトの性質によって最適解が変わります。
重要なのは「何となく」で選ばないことです。

CIでComposer installを実行する構成

最もシンプルで、多くのプロジェクトで最初に採用されがちな構成です。

どんな構成か

CIのジョブ内で、次のような流れになります。

composer install --no-interaction --prefer-dist
phpunit

CIが毎回Composer installを実行し、その結果を使ってテストやビルドを行います。

この構成のメリット

  • 設定が分かりやすい
  • ローカルとCIの差が小さい
  • 小規模〜中規模では十分実用的

特に、開発初期や人数の少ないチームでは、考えることが少なく済むのが利点です。

よくある落とし穴

一方で、次のような問題が起きやすいです。

  • CIの実行時間が長くなる
  • Composerのバージョン差で挙動が変わる
  • lockファイルの扱いが雑になりがち

例えば、composer.lockを更新せずにcomposer installを実行すると、CIと本番でインストールされるライブラリの細かいバージョンがズレる可能性があります。
「CIは通ったのに本番でエラーが出る」という典型例です。

依存関係をビルド成果物に含める構成

次に多いのが、Composer installをビルド工程に閉じ込め、成果物としてまとめるやり方です。

どんな構成か

CIでは次のように扱います。

  • ビルド用ジョブでComposer install
  • vendorディレクトリを含めてアーカイブ
  • デプロイ時は展開するだけ

この場合、デプロイ先ではComposerを実行しません。

この構成のメリット

  • 本番環境でComposerが不要
  • デプロイが高速で安定する
  • 本番とCIの差分が減る

特に、サーバー台数が多い構成や、スケールアウトするシステムでは効果が大きいです。

注意すべき点

ただし、この構成にも注意点があります。

  • OSやPHP拡張の差に弱い
  • ビルド環境と本番環境を揃える必要がある

例えば、CIはLinux、本番は別ディストリビューション、という場合、ネイティブ拡張を含むライブラリで問題が出ることがあります。
Dockerなどで環境を揃えないと、かえって不安定になるケースもあります。

CIではComposerを極力使わない構成

やや上級者向けですが、CI/CDでComposerの存在感を減らす設計もあります。

どんな考え方か

  • Composerは開発時のみ使用
  • lockファイルとvendorを厳密に管理
  • CIは成果物の検証に専念

この場合、CIは「正しい成果物かどうか」を確認するだけで、依存解決はしません。

向いているケース

  • リリースフローが厳格
  • 依存関係の変更頻度が低い
  • 運用チームと開発チームが分かれている

一方で、開発の自由度は下がるため、全てのチームに向いているわけではありません。

composer.lockの扱いで失敗しがちな話

CI/CDとComposerの話で、最もトラブルが多いのがcomposer.lockです。

よくある失敗

  • lockファイルをコミットしない
  • CIでcomposer updateを実行する
  • 本番でlockを無視してinstallする

これらはすべて、環境差異を生みやすい行為です。

基本的な考え方

  • composer.lockは必ず管理する
  • CIではcomposer installを使う
  • updateは意図的に行う

「いつ、誰が、なぜ依存関係を更新したのか」を追える状態にしておくことが、CI/CDでは特に重要です。

CI/CDでComposerを使う際の実践的な設定例

最後に、比較的バランスの良い設定例を紹介します。

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

この設定では、次の点を意識しています。

  • CIでは対話を避ける
  • 本番不要な依存を除外する
  • オートローダを最適化する

「とりあえず動けばいい」から一歩進んだ設定として、多くの現場で使われています。

リスクと注意点

CI/CDでComposerを扱う以上、完全にリスクをゼロにはできません。

  • レジストリ障害の影響を受ける
  • 外部依存が増えるほど不安定になる
  • キャッシュ戦略を誤ると逆に遅くなる

そのため、CIが失敗したときに「Composerが原因かどうか」を切り分けられる状態を作っておくことが大切です。

まとめ:結局どう扱うのが現実的か

CI/CDでComposerをどう扱うべきかは、「正解を探す」よりも「前提を揃える」ことが近道です。
開発・CI・本番のどこで依存関係を解決するのかを明確にし、そのルールを崩さないことが、長期的には一番の安定策になります。

Composerは便利ですが、魔法の箱ではありません。
CI/CDの中で役割を決めてあげることで、初めて安心して使えるツールになるのだと思います。