💭

Laravel Docker イメージサイズ削減に挑戦!~実践と効果~

2024/12/31に公開

Dockerイメージサイズを削減することは、プロジェクトの効率化やコスト削減において非常に重要な取り組みです。特に、Laravelのようなフレームワークを使ったプロジェクトでは、サイズが膨らみがちで、ビルドやデプロイの速度が遅くなることがあります。

今回、私は約400MBのイメージを約200MBまで削減することに成功しました。その過程で得た知見や具体的な手法を、実例を交えてご紹介します。


イメージサイズ削減のメリット

Dockerイメージのサイズを小さくすることには、以下のようなメリットがあります。

  1. ビルド時間の短縮
    イメージのサイズが小さくなると、ビルドやプッシュ/プルの速度が向上し、デプロイや環境構築の時間が大幅に削減されます。

  2. ストレージコストの削減
    軽量化されたイメージはストレージの使用量が減るため、クラウドのストレージコストやデータ転送費用の削減に繋がります。

  3. セキュリティ向上
    不要なファイルやパッケージを削除することで、攻撃対象が減り、セキュリティリスクを軽減できます。


実践結果:イメージサイズを50%削減!

400MBあったDockerイメージを、以下の3つの手法を使って200MBまで削減しました。それぞれの方法と効果を順を追って解説します。


1. 不要ファイルのコピーをやめる(効果:高)

最大の効果を発揮したのがこの手法です。 Laravelプロジェクトには、動作に不要なディレクトリやファイル(例:テストコード、ドキュメント、CI/CD設定など)が含まれています。これらをイメージに含めないだけで、驚くほどサイズを削減できます。

修正前のDockerfile:

COPY . .
RUN composer install

修正後のDockerfile:

COPY . .
RUN composer install --prefer-dist --optimize-autoloader --no-dev
# Laravelを動かす際に不要なディレクトリを削除
RUN rm -rf /.ci \
           /.github \
           /certs \
           /docker \
           /docs \
           /hooks \
           /lambda \
           /packages \
           /Sniffs \
           /storage \
           /stubs \
           /tests

2. Alpineイメージの使用(効果:中)

Dockerイメージのサイズ削減で定番なのが、Alpine Linuxベースのイメージを使用することです。Alpineイメージは軽量で、通常のDebianベースイメージよりも数分の一のサイズです。

Alpineイメージのメリット

  • 軽量化:イメージサイズが小さく、効率的に動作。
  • セキュリティ性:最小限のコンポーネントのみを含むため、セキュリティの攻撃対象が減少。

Alpineイメージ使用時の注意点

  • 必要なパッケージがデフォルトでインストールされていないため、明示的に追加が必要。
  • glibc非互換の問題に注意(Laravelでは通常影響は少ない)。

Alpineを使ったDockerfileの例:

FROM composer:latest as composer
FROM php:8.3-fpm-alpine

RUN set -eux \
    && apk add --no-cache --virtual .php-build-deps \
    ・
    ・
    ・

3. 不要パッケージをインストールしない(効果:低)

初めの段階では、多くのパッケージをインストールしていましたが、実際に必要なものだけを厳選しました。Laravelが動作するために必要な最小限の拡張機能だけをインストールし、余計なものは省きました。

修正前のDockerfile:

FROM php:8.3-fpm

RUN docker-php-source extract \
    && apt-get update \
    && apt-get install -y libbz2-dev \
      libxml2-dev \
      libssl-dev \
      zlib1g-dev \
      libpng-dev \
      libonig-dev \
      libsodium-dev \
      libxslt-dev \
      libzip-dev \
      netcat-openbsd \
      unzip \
    && docker-php-ext-install bcmath \
      bz2 \
      calendar \
      ctype \
      dom \
      exif \
      fileinfo \
      ftp \
      gd \
      gettext \
      iconv \
      intl \
      mbstring \
      mysqli \
      opcache \
      pdo_mysql \
      pdo \
      simplexml \
      sockets \
      sodium \
      xml \
      xmlwriter \
      xsl \
      zip \
    && pecl install igbinary \
    && docker-php-ext-enable igbinary \
    && pecl install msgpack \
    && docker-php-ext-enable msgpack \
    && pecl install redis \
    && docker-php-ext-enable redis \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

修正後のDockerfile:

FROM php:8.3-fpm-alpine

RUN set -eux \
    && docker-php-source extract \
    && apk update \
    && apk add --no-cache --virtual .php-build-deps \
      libpng-dev \
      libxslt-dev \
      libzip-dev \
      gettext-dev \
      icu-dev \
      linux-headers \
      gcc \
      g++ \
      make \
      autoconf \
      tzdata \
    && docker-php-ext-install bcmath \
      bz2 \
      calendar \
      exif \
      ftp \
      gd \
      gettext \
      intl \
      mysqli \
      opcache \
      pdo_mysql \
      sockets \
      xsl \
      zip \
    && pecl install igbinary \
    && docker-php-ext-enable igbinary \
    && pecl install msgpack \
    && docker-php-ext-enable msgpack \
    && pecl install redis \
    && docker-php-ext-enable redis \
    && cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime \
    && apk del tzdata \
    && rm -rf /var/cache/apk/*

まとめ

Dockerイメージサイズ削減の効果を比較すると、以下の順序で効果が高いことがわかりました。

  1. 不要ファイルのコピーをやめる(手軽かつ効果大)
  2. Alpineイメージの使用(中程度の工数で効果中)
  3. 不要パッケージをインストールしない(調整が必要だが効果小)

特に「不要ファイルのコピーをやめる」は、手間が少なく即座に効果を得られるため、これから取り組む方に強くおすすめします。Laravelプロジェクトだけでなく、他のフレームワークにも応用可能です。ぜひ一度試してみてください!

Discussion