マルチステージビルドでイメージサイズを劇的に削減できるべ

B!

PHPアプリケーションのコンテナイメージを作成する際、ビルドに必要なツール(Composer、各種コンパイラなど)をすべて含めてしまうと、イメージが肥大化し、セキュリティリスクも増大します。

この課題を解決するのが、コンテナビルドの効率を最大化する技術、マルチステージビルドです。

マルチステージビルドとは?

マルチステージビルドとは、一つのDockerfile内で複数のFROM命令(ステージ)を定義し、最終的なイメージにデプロイに必要なファイルだけをコピーする手法です。

役割分担

  1. ビルドステージ (Build Stage):
    • 目的: アプリケーションのビルドと依存関係の解決。
    • 使用イメージ: 大きなイメージ(例: composer:latestphp:8.3-fpmなど)。
    • 作業: Composerによる依存パッケージのインストール、フロントエンドアセットのコンパイル、テストの実行などを行います。
    • 特徴: このステージは最終的なデプロイには使用されません。
  2. 最終ステージ (Final Stage):
    • 目的: アプリケーションの実行環境の構築。
    • 使用イメージ: 軽量なイメージ(例: php:8.3-fpm-alpinedistrolessなど)。
    • 作業: ビルドステージで生成された成果物(例: vendorディレクトリ、コンパイル済みバイナリ、PHPコード)のみをコピーします。

メリット

  • イメージサイズの劇的な削減: ビルドツールやキャッシュ、開発用の依存関係が最終イメージから完全に除外されます。
  • セキュリティ向上: 最終イメージが最小限の構成になるため、攻撃対象となる領域が縮小します。
  • ビルド時間の短縮: 軽量なイメージを使用することで、プル時間が短くなります。

PHPアプリケーションでのマルチステージビルド

PHPアプリケーションの典型的なマルチステージビルドは、Composerによる依存関係の解決を分離することに焦点を当てます。

Dockerfile

以下のDockerfileは、Composerで依存関係を解決するステージと、それを使ってアプリケーションを実行する最小限のステージに分離しています。

# ------------------------------------
# 📌 ステージ 1: composer_stage (依存関係の解決)
# ------------------------------------
# composerツールとPHP環境が揃ったイメージを使用
FROM composer:latest AS composer_stage

# --------------------------------------------- # ステージ1: composer_stage(依存関係の解決) # --------------------------------------------- # composer ツールとPHP環境が揃ったイメージを使用 FROM composer:latest as composer_stage WORKDIR /app # 依存関係管理ファイルをコピー COPY composer.json composer.lock # 本番用のインストール RUN composer install --no-dev --optimize-autoloader # --------------------------------------------- # ステージ2: final_stage (最小限の実行環境) # --------------------------------------------- # 軽量でFPMが含まれるAlpineベースのイメー火 FROM php:8.3-fpm-alpine AS final_stage # セキュリティベストプラクティス:非特権ユーザーの設定 RUN adduser -D nonroot USER nonroot WORKDIR /app # --chown=nonroot:nonroot で、コピーと同時にファイルの所有者を非特権ユーザーに変更 COPY --from=composer_stage --chown=nonroot:nonroot /app/vendor /app/vendor # アプリケーションのコード全体をコピー COPY --chown=nonroot:nonroot # PHP-FPM を起動コマンドとする(NginxなどのWebサーバーと連携して使用 CMD ["php-fpm"]

 

実行手順

  1. プロジェクトルートに配置: 上記のDockerfileをプロジェクトのルートディレクトリに配置します。
  2. docker buildを実行: 通常通りdocker buildコマンドを実行するだけです。Dockerエンジンが自動的にマルチステージビルドを処理します。
docker build -t my-php-app:prod .

 

PHPでのポイント

  1. composer_stageの利用: Composerをインストールする手間を省くため、公式のcomposerイメージをビルダーとして使うのが最も効率的です。
  2. --no-dev: 開発時のみ必要なパッケージ(テストフレームワークなど)は最終イメージに含めないようにします。
  3. USER nonroot: セキュリティのため、最終ステージでは必ずroot権限を放棄し、非特権ユーザーでアプリケーションを実行するように設定しましょう。(これにより、低ポート番号の使用には制約が生じますが、セキュリティが大幅に向上します)
  4. COPY --fromの活用: この命令が全てです。Composerの巨大なキャッシュやビルドツール群を最終イメージから排除し、必要なvendorディレクトリだけをクリーンにコピーします。

マルチステージビルドは、軽量で安全なPHPコンテナイメージを作成するための必須技術です。ぜひあなたのプロジェクトに導入してください。

最新の記事はこちらから