PHP イメージをバージョンアップ
PHP イメージをバージョンアップ
Docker Hub > Official images / php のイメージをバージョンアップするときの確認事項をまとめます。
例として、Dockerfile の FROM を次のように変更するケースを考えます。PHP のバージョン(8.2 → 8.3)と、ベースの OS である Debian のバージョン(11 → 12)が同時に上がります。
- FROM php:8.2-fpm-bullseye
+ FROM php:8.3-fpm-bookworm
| コードネーム | バージョン | リリース日 |
|---|---|---|
| bullseye | Debian 11 | 2021年8月14日 |
| bookworm | Debian 12 | 2023年6月10日 |
バージョンアップする理由
- Debian 11(bullseye)は LTS も含めてサポートが終了しています(2026年8月31日)
php:8.3-fpm-bullseyeタグは 2025年8月以降更新されておらず、セキュリティ修正が入りません。8.3 に上げるなら bookworm を使います
確認の範囲
ここで扱うのは、パッケージが見つからない、拡張モジュールのコンパイルに失敗するといったインフラ面の互換性だけです。PHP のバージョンアップによるアプリケーションコードの互換性(非推奨になった関数など)は扱いません。
docker build が成功しても、すべてが確認できたわけではありません。インストール方法ごとに、ビルドで分かることと、別に確認が必要なことは次のとおりです。
| インストール方法 | ビルドの成功で分かること | 別に確認が必要なこと |
|---|---|---|
APT(apt-get install) |
パッケージが見つかり、エラーなくインストールできた | 入ったバージョンが想定どおりか |
PHP 拡張モジュール(docker-php-ext-install / pecl install) |
コンパイルが通った | PHP の起動時に読み込めるか、php-fpm の設定が正しいか |
| その他(curl などで直接入れたもの) | コマンドがエラーで終わらなかった | 正しいファイルが入り、動くか |
以降のコマンド例の <イメージ名> は、確認したいイメージの名前に置き換えてください。
APT パッケージ
ビルドの成功で分かること
APT のパッケージは Debian がビルド済みのバイナリ(.deb)なので、インストール時にコンパイルはしません。ビルドが成功すれば、次の処理がすべてエラーなく終わったことが分かります。
- ダウンロード
- 依存関係の解決
- 展開
- パッケージ付属のセットアップスクリプトの実行
OS のバージョンアップでパッケージ名がなくなったり変わったりした場合は、apt-get install が失敗するので、ビルドの時点で気づけます。
公式リポジトリのパッケージは、そのリリース向けに依存関係込みで用意されています。そのため「入ったのに動かない」ことはまず起きません。
ビルドでは分からないこと
パッケージ名が同じでも、中身のバージョンは OS ごとに変わります。 ビルドは通るので気づきにくい点です。
| パッケージ | bullseye | bookworm |
|---|---|---|
default-mysql-client |
MariaDB 10.5 のクライアント | MariaDB 10.11 のクライアント |
libicu-dev(PHP の intl が使う ICU) |
ICU 67 | ICU 72 |
default-mysql-client は、名前に反して MySQL ではなく MariaDB のクライアントを入れます。
確認したい場合は、コンテナを起動してバージョンを表示します。
docker run --rm <イメージ名> mysql --version
なお、zlib1g-dev や libicu-dev などの -dev パッケージは、PHP 拡張をコンパイルするための部品です。PHP 拡張のコンパイルが通れば、これらが正しく入ったことも確認できます。
PHP 拡張モジュール(extension)
ビルドの成功で分かること
docker-php-ext-install や pecl install は、イメージの中でソースコードから拡張をコンパイルします。途中の make が失敗すると終了コードが 0 以外になり、ビルドが止まります。
ビルドが成功すれば、拡張がそのイメージの PHP に対してコンパイルできたことが分かります。PHP のバージョンを上げたときに最も壊れやすいのはここなので、ビルドが通ること自体が大きな確認になります。
ビルドでは分からないこと
拡張モジュールを読み込めるか
コンパイルが通っても、PHP の起動時に拡張の .so を読み込めないことがあります(依存ライブラリが足りない、など)。
php -m で確認できますが、読み込みに失敗しても php -m は Warning を出すだけで、終了コードは 0 です。そのため、出力に Warning が含まれていないかを grep で確認します。
output=$(docker run --rm <イメージ名> php -m 2>&1)
echo "${output}"
if echo "${output}" | grep -E 'PHP Warning|PHP Fatal error|Unable to load'; then
echo "PHP extension failed to load"
exit 1
fi
この方法では、Dockerfile や php.ini から拡張の記述そのものを消してしまった場合は検出できません。
php-fpm の設定が正しいか
php-fpm -t は php-fpm の設定ファイル(php-fpm.conf と php-fpm.d/*.conf)を読み込んで検証し、そのまま終了します。設定に誤りがあれば、終了コードが 0 以外になります。
docker run --rm <イメージ名> php-fpm -t
php-fpm -t は拡張モジュールの読み込みに失敗しても成功を返します。拡張の確認は php -m で行ってください。
その他(curl などで直接入れたもの)
curl などで直接ダウンロードしてインストールしたものは、ビルドが成功しても正しく入ったとは限りません。Docker のビルドで分かるのは「コマンドがエラーで終わらなかった」ことだけで、ダウンロードしたファイルの中身が正しいかや、実際に動くかまでは確認しないからです。
特に注意が必要なのは次の 2 つです。
- curl は
-fを付けないと、404 などのエラーページが返ってきても成功扱い(終了コード 0)になります。 壊れたファイルを入れたままビルドが通ることがあります RUNでa | bのようにパイプでつなぐと、aが失敗してもbが成功すればビルドは通ります。RUNは/bin/sh -cで実行され、pipefailが効かないためです
curl などで入れたものは、コンテナを起動してコマンドを実行し、動作を確認してください。
docker run --rm <イメージ名> composer --version