レガシーPHPリファクタ 18:レガシーSmarty環境を救う!Docker環境をXAMPPからPHP公式イメージ(Debian trixie PHP 8.5)へ移行した話

今回のテーマは、「Dockerfile の全面刷新」、開発基盤の根幹である Dockerfile の近代化(XAMPP環境からPHP公式Dockerイメージへの移行) について取り上げます。

書籍執筆当時の2007年は、Windows + XAMPP が定番でした。その後、GitHub公開に向けてLinux環境へ移植し、CentOS + XAMPP の組み合わせ(最終的には almalinux:8.10 + xampp-linux-x64-7.4.11)で追従させてきました。

しかし、XAMPPをベースにしたDockerイメージ運用には、ビルドの遅さやセキュリティ面での懸念など、多くのレガシーな課題がありました。そこで今回のPRでは、PHP公式Dockerイメージへの移行を行いました。

移行の軌跡:XAMPPからPHP公式イメージへ

これまでのコンテナ環境の変遷を振り返ると、OSやPHPのバージョンを少しずつ、またはドラスティックにアップデートしてきました。

  • XAMPP時代(一部抜粋)
    • centos:6 + xampp-linux-1.7.1 (PHP 5.2.9)
    • centos:6 + xampp-linux-1.8.1 (PHP 5.4.7)
    • centos:7 + xampp-linux-x64-5.6.40
    • almalinux:8.10 + xampp-linux-x64-7.4.11 (修正前のコード)
  • PHP公式Dockerイメージへの移行期
    • php:7.4.11-apache-buster からスタートし、バージョンを .1 ずつ地道に引き上げ
    • php:8.0 〜 php:8.4 を経て、最新の php:8.5.12-apache-trixie へ (修正後のコード)

比較:修正前と修正後のコード

修正前:CentOS 7 + XAMPP時代 (almalinux:8.10)

修正前は、ベースOSにAlmaLinuxを使用し、巨大なXAMPPのインストーラをダウンロードして無人インストール(--mode unattended)を実行していました。

FROM almalinux:8.10

# TimeZoneの設定
RUN echo 'ZONE"=Asia/Tokyo"' > /etc/sysconfig/clock

RUN yum install -y net-tools
RUN yum install -y wget

RUN wget --version
RUN wget "https://jaist.dl.sourceforge.net/project/xampp/XAMPP%20Linux/7.4.11/xampp-linux-x64-7.4.11-0-installer.run"
RUN chmod +x xampp-linux-x64-7.4.11-0-installer.run
RUN ./xampp-linux-x64-7.4.11-0-installer.run --version
RUN ./xampp-linux-x64-7.4.11-0-installer.run --enable-components xampp_developer_files --mode unattended

EXPOSE 80 3306

CMD "/bin/sh"

修正後:PHP公式Dockerイメージ (php:8.5.12-apache-trixie)

修正後では、PHP公式イメージをベースにし、拡張機能のインストールやComposerのマルチステージ風コピーを取り入れたモダンな構成へと生まれ変わりました。

FROM php:8.5.12-apache-trixie

# PHP Core Extensions
# @see https://hub.docker.com/_/php
# mbstring, pdo, dom, xml はデフォルトでインストール済み
RUN set -x \
    # TimeZoneの設定 \
    && ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime \
    && apt-get update -o Acquire::Check-Valid-Until=false || apt-get update \
    && apt-get install -y --no-install-recommends \
        # CLI用 mysql コマンド \
        default-mysql-client \
        # Golden Master Test 前後のデータリセットで必要 \
        git \
        # gd関数で必要 \
        libfreetype6-dev \
        libjpeg62-turbo-dev \
        libpng-dev \
        libzip-dev \
        # intl で必要 \
        libicu-dev \
        # intl xml関数で必要 \
        libxml2-dev \
        libsqlite3-dev \
        # composer installで必要 \
        unzip \
    && docker-php-ext-configure gd --with-freetype --with-jpeg \
    && docker-php-ext-install -j"$(nproc)" \
        # composer-require-checker ^4.18 で必要 \
        bcmath \
        gd \
        # composer-require-checker ^4.18 で必要 \
        intl \
        mysqli \
        pdo_mysql \
        pdo_sqlite \
        # smarty/smarty のinstallで必要
        zip \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

COPY *.sed /root/

RUN set -x \
    && cp /usr/local/etc/php/php.ini-development /usr/local/etc/php/php.ini \
    && sed -ri --file=/root/php_ini.sed /usr/local/etc/php/php.ini \
    # Xdebug のインストールと有効化 \
    && pecl install xdebug \
    && docker-php-ext-enable xdebug \
    && echo "xdebug.start_with_request = yes" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini

# Composer の最新公式イメージからバイナリだけをコピーする
COPY --from=composer:2.10.3 /usr/bin/composer /usr/local/bin/composer

COPY entrypoint.sh /usr/local/bin/entrypoint.sh
RUN set -eux \
    && chmod +x /usr/local/bin/entrypoint.sh

# WORKDIR、ENTRYPOINT、CMDの順序がお作法
WORKDIR /var/www/html

ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
CMD ["apache2-foreground"]
smartybook/docker/php-web/Dockerfile at main · ninton/smartybook
Smarty動的Webサイト構築入門サンプルソース. Contribute to ninton/smartybook development by creating an account on GitHub.

また、ディレクトリ構成も docker/php-web/ と docker/mariadb-db/ にすっきりと整理されています。

docker/
├── mariadb-db
│   ├── init
│   │   └── db_init.sql
│   └── my.cnf
└── php-web
    ├── Dockerfile
    ├── entrypoint.sh
    └── php_ini.sed


移行による4つの劇的な改善点

今回の移行によって、開発効率・保守性・セキュリティ・パフォーマンスのあらゆる面で大きなメリットがもたらされました。

1. ビルド時間とパフォーマンスの大幅な短縮

  • XAMPPインストーラの廃止: 修正前は数分以上かかっていた巨大なXAMPPファイルのダウンロードと無人インストールの処理が完全になくなりました。
  • オーバーヘッドの削減: PHP公式の php:8.5.12-apache-trixie をベースにすることで、ビルドやコンテナ起動にかかる時間が劇的に短縮されています。

2. 保守性とセキュリティの向上(最新環境への追従)

  • モダンな基盤: サポートが終了した古いCentOSやPHP 7.4から、最新のDebian(trixie)およびPHP 8.5へ一気にキャッチアップしました。
  • Renovateによる自動追従: PHP 8.5.12 や Composer 2.10.3 のようにパッチバージョンまで厳密に指定しつつ、Renovateによる自動更新の仕組みを組み込んでいます。これにより、セキュリティパッチの適用漏れを防ぎ、手動メンテのコストをゼロにしています。

3. ディレクトリ構成とベストプラクティスの準拠

  • 見通しの良い構造: アプリケーション側(docker/php-web/)とデータベース側(docker/mariadb-db/)に綺麗に分離され、標準的な Docker 開発のプラクティスに準拠した構造になりました。
  • 正しいインストラクション順序: WORKDIR、ENTRYPOINT、CMD をDockerのお作法に則った正しい順序で記述し、コンテナの挙動を直感的にしています。

4. 拡張機能とツールのスマートな管理

  • 公式ヘルパーの活用 (docker-php-ext-install): gd、intl、bcmath、zip などの拡張モジュールや依存ライブラリを公式の作法で安全かつ簡潔にビルドしています。
  • イメージの軽量化: apt-get clean や rm -rf /var/lib/apt/lists/* を同一レイヤー内で実行し、不要なキャッシュを残さない工夫を施しています。
  • Composerのピンポイント取得: COPY --from=composer:2.10.3 を使い、Composerの公式バイナリだけをスマートに取り込んでいます。

まとめ

「遅い・古い・属人的」だったレガシーなXAMPP開発環境から、「高速・モダン・自動化された」プロフェッショナルなDocker環境へと生まれ変わりました。

レガシーSmartyを扱う現場であっても、開発基盤(Docker)をモダンに整えることで、PHPのバージョンアップやリファクタリングの心理的ハードルはグッと下がります。古いシステムと向き合うエンジニアの皆さんの参考になれば幸いです。

おまけ:Dockerfileの記述で気をつけている2つのマイルール

ぼくはインフラの専門家ではありませんが、レガシーな現場や新規開発でDockerfileをコピペして回す中で、「こうしておくと後々で絶対に助かる」と感じているマイルールが2つあります。

  1. 「なぜ必要か」をコメントに残す

コピペしたときに「これ消していいんだっけ?」と迷ったり、知らずに消してツールが動かなくなったりするのを防ぐため、モジュールごとに理由をコメントするようにしています。

        # Golden Master Test 前後のデータリセットで必要 \
        git \
        # gd関数で必要 \
        libfreetype6-dev \
  1. 1行1モジュールにし、アルファベット順にソートする

スペース区切りの長い1行にすると、モジュールの有無を見落として重複指定したり、Gitの差分(Diff)が汚くなったりします。ソートしておけば差分も綺麗になり、メンテナンス性が劇的に上がります。

参考コード

smartybook/docker/php-web/Dockerfile at main · ninton/smartybook
Smarty動的Webサイト構築入門サンプルソース. Contribute to ninton/smartybook development by creating an account on GitHub.
レガシーPHPリファクタ 18:レガシーSmarty環境を救う!Docker環境をXAMPPからPHP公式イメージ(Debian trixie PHP 8.5)へ移行した話
Smarty動的Webサイト構築入門サンプルソース. Contribute to ninton/smartybook development by creating an account on GitHub.

タイトルとURLをコピーしました