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

title

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:build_stage(依存関係の解決)
# =============================================
FROM composer:latest AS build_stage 
WORKDIR /app 
# 先に依存関係ファイルだけをコピー(キャッシュ効率化のため)
COPY composer.json composer.lock ./ 
# 本番環境用に最適化してインストール 
# --no-dev: 開発用パッケージを除外
# --optimize-autoloader: オートローダーを最適化して高速化 
RUN composer install \
--no-dev \
--no-interaction \
--optimize-autoloader 
# =============================================
# ステージ2:final_stage(最小限の実行環境)
# =============================================
# 軽量なAlpine LinuxベースのPHP-FPMイメージを使用
FROM php:8.3-fpm-alpine AS final_stage 
# セキュリティ:実行用の非特権ユーザーを作成
RUN adduser -D appuser
USER appuser
WORKDIR /var/www/html
# ステージ1からvendorディレクトリのみをコピー
# --chown で所有権を同時に変更するのがポイント
COPY --from=build_stage --chown=appuser:appuser /app/vendor ./vendor
# アプリケーションのソースコードをコピー
COPY --chown=appuser:appuser . .
 
# PHP-FPMを起動 
EXPOSE 9000
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コンテナイメージを作成するための必須技術です。ぜひあなたのプロジェクトに導入してください。

投稿者 hrokig2

沖縄でシステム開発やってます

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です


reCaptcha の認証期間が終了しました。ページを再読み込みしてください。