はじめに

弊社はおもにバックエンドのプログラム言語に PHP を使用します。
また多くのアプリがコンテナで動いています。

コンテナはコントロールプレインを Amazon ECS、データプレインは AWS Fargate を使用することが多くイメージは Docker を使用してビルドします。

本記事では Docker で PHP を使用する際に必要になることが多い PHP 拡張モジュール1をインストールする方法を簡単にまとめたいと思います。

(ベース)イメージ

本記事は Docker Hub の 2024-03-06 時点の php:latest を使用します。 はじめに上記イメージの OS、PHP バージョンおよびインストール済み拡張モジュールを確認しておきます。

OS

$ docker run php:latest cat /etc/os-release

PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
# .....

PHP

docker run php:latest php -v

PHP 8.3.3 (cli) (built: Feb 16 2024 20:53:43) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.3.3, Copyright (c) Zend Technologies

インストール済み拡張モジュール

$ docker run php:latest php -m

[PHP Modules]
Core
ctype
# .....
# .....
xmlwriter
zlib

[Zend Modules]

拡張モジュールをインストール

本記事では、 Docker に PHP 拡張モジュールをインストールする代表的なコマンド docker-php-ext-install コマンドと pecl コマンドを紹介します2

docker-php-ext-install コマンド

docker-php-ext-install コマンドは PHP 拡張モジュールを Docker にインストールするヘルパーコマンドです。インストールだけでなく有効化( ini ファイル作成)もします。 docker-php-ext-install コマンドを使用できる拡張モジュールは以下の方法で確認できます( PECL 以外の拡張モジュールは概ね使用できるようです)。

$ docker run php:latest docker-php-ext-install --help

# .....
Possible values for ext-name:
bcmath bz2 calendar ctype curl dba dl_test dom enchant exif ffi fileinfo filter ftp gd gettext gmp hash iconv imap intl json ldap mbstring mysqli oci8 odbc opcache pcntl pdo pdo_dblib pdo_firebird pdo_mysql pdo_oci pdo_odbc pdo_pgsql pdo_sqlite pgsql phar posix pspell random readline reflection session shmop simplexml snmp soap sockets sodium spl standard sysvmsg sysvsem sysvshm tidy tokenizer xml xmlreader xmlwriter xsl zend_test zip
# .....

docker-php-ext-install コマンド使用方法

拡張モジュール名を引数にとります。
Dockerfile は以下のようになります。

RUN docker-php-ext-install {{ 拡張モジュール名 }}

前述したように docker-php-ext-install コマンドはインストールだけでなく有効化もします。 php:latest では /usr/local/etc/php/conf.d/ ディレクトリに docker-php-ext-{{ 拡張モジュール名 }}.ini が作成されます。 後述する pecl コマンドのように docker-php-ext-enable を実行する必要はありません。

例) Zip 拡張モジュール

WordPress でも推奨されている Zip 拡張モジュールをインストールします3
Dockerfile は以下のようになります4

FROM php:latest

RUN apt-get update \
 && apt-get upgrade -y \
 && apt-get install -y \
    libzip-dev

RUN docker-php-ext-install \
    zip

Dockerfile をビルドします。

$ docker build -t sample:latest .

Zip 拡張モジュールが追加されています。

$ docker run sample:latest php -m

[PHP Modules]
Core
ctype
# .....
# .....
xmlwriter
zip                 # Zip 拡張モジュールがインストール
zlib

[Zend Modules]

ini ファイル

ini ファイルが作成されていることを確認します。

$ docker run sample:latest cat /usr/local/etc/php/conf.d/docker-php-ext-zip.ini
extension=zip.so

依存パッケージ

PHP 拡張モジュールは依存パッケージを必要とする場合があります。 Zip 拡張モジュールは Debian の libzip-dev パッケージを必要とします。

PHP 拡張モジュールを初めてインストールするときのハードルとして、どの依存パッケージをインストールすればよいか迷う点があるのではと思います。 参考程度ですが依存パッケージの見つけ方を書きます。

  1. 公式ドキュメント > 拡張モジュールの一覧/分類 > 所属 を確認する
  2. Zip 拡張モジュールは外部拡張セクションにあるので何らかの依存パッケージが必要になる
  3. Zip 拡張モジュールの 要件 に libzip の記載がある

Debian で libzip の開発向けパッケージを探します5

docker run --rm debian:latest /bin/bash -c "apt-get update &&  apt-get upgrade -y && apt-cache search libzip"

# ....
libzip-ocaml-dev - OCaml compression libraries (development files)
libzip-dev - library for reading, creating, and modifying zip archives (development)
libzip4 - library for reading, creating, and modifying zip archives (runtime)
libzip4j-java - java library for zip files
# ....

libzip-dev が該当しそうだと当たりが付けられます。

pecl コマンド

PECL( The PHP Extension Community Library )に分類される PHP 拡張モジュールは pecl コマンドを使ってインストールします。 どの拡張モジュールが PECL かは、公式マニュアルの 所属 > PECL 拡張 で確認できます6

pecl コマンド使用方法

拡張モジュール名を引数にとります。
Dockerfile は以下のようになります。

pecl install コマンドは docker-php-ext-install コマンドのように拡張モジュールを有効化しません。 docker-php-ext-enable コマンドで有効化するか ini ファイルを作成して有効化します。

docker-php-ext-enable を使って有効かする例を記載します。

RUN pecl install \
    {{ 拡張モジュール名 }} \
 && docker-php-ext-enable \
    {{  拡張モジュール名 }}

docker-php-ext-enable コマンドは /usr/local/etc/php/conf.d/docker-php-ext-{{ 拡張モジュール名 }}.ini を作成します。

例) APCu 拡張モジュール

FROM php:latest

RUN apt-get update \
 && apt-get upgrade -y \
 && apt-get install -y

RUN pecl install \
    apcu \
 && docker-php-ext-enable \
    apcu

APCu 拡張モジュールの 要件 に「外部ライブラリは必要ありません。」と記載されているので依存パッケージは必要ありません。

ini ファイル

ini ファイルが作成されていることを確認します。

$ docker run sample:latest cat /usr/local/etc/php/conf.d/docker-php-ext-apcu.ini
extension=apcu.so

おわりに

簡単ですが docker-php-ext-install コマンドと pecl コマンドを使って、Docker に PHP 拡張モジュールをインストールする方法をご紹介しました。

Docker を使用する機会は今後も増えると思います。
本記事が参考になれば幸いです。

  1. 本記事は PHP Extension を公式ドキュメント日本語訳に合わせて PHP 拡張モジュールと表記します。 

  2. pecl は Docker に限らず PECL( The PHP Extension Community Library )のインストールに使用します。 

  3. WordPress に必要な拡張モジュール一覧 

  4. 詳細は省きますが、apt-get update、 apt-get upgrade はパッケージリポジトリを最新にしてアップグレードできるパッケージをアップグレードします。 

  5. 実際には依存パッケージが他のパッケージに依存していることも多くDocker Build のエラーメッセージを参考にヒューリスティックに解決する場合も多くあります。 

  6. 記載のない PECL パッケージもあります。 https://pecl.php.net/ でも検索しみてください(例 gRPC)。