Dockerfileリーディング PHP-FPM公式イメージ(2)
前回記事からの続きです。引き続きPHPの公式イメージを読み解いていきます。
Dockerイメージ6層目(90行目)から読み進めていきます。
Dockerイメージ 6層目
COPY docker-php-source /usr/local/bin/
phpのソースを展開するスクリプトを/usr/local/binにコピーします。
Dockerイメージ 7層目
Dockerイメージ 7層目(1/6)
RUN set -eux; \ apk add --no-cache --virtual .build-deps \ $PHPIZE_DEPS \ argon2-dev \ coreutils \ curl-dev \ libedit-dev \ libsodium-dev \ libxml2-dev \ openssl-dev \ sqlite-dev \ ; \ \ export CFLAGS="$PHP_CFLAGS" \ CPPFLAGS="$PHP_CPPFLAGS" \ LDFLAGS="$PHP_LDFLAGS" \ ; \ docker-php-source extract; \ ★続く
91-101行目: PHPをビルドする際に必要なパッケージを導入し、
104-107行目: ビルドオプションを設定後、
108行目: PHPのソースファイルを展開しています。
Dockerイメージ 7層目(2/4)
cd /usr/src/php; \ gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \ ./configure \ --build="$gnuArch" \ --with-config-file-path="$PHP_INI_DIR" \ --with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \ \ # make sure invalid --configure-flags are fatal errors intead of just warnings --enable-option-checking=fatal \ \ # https://github.com/docker-library/php/issues/439 --with-mhash \ \ # --enable-ftp is included here because ftp_ssl_connect() needs ftp to be compiled statically (see https://github.com/docker-library/php/issues/236) --enable-ftp \ # --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195) --enable-mbstring \ # --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself) --enable-mysqlnd \ # https://wiki.php.net/rfc/argon2_password_hash (7.2+) --with-password-argon2 \ # https://wiki.php.net/rfc/libsodium --with-sodium=shared \ \ --with-curl \ --with-libedit \ --with-openssl \ --with-zlib \ \ ★ 続く
109行目 : 展開したソースディレクトリに入り、
111-137行目: ソースファイルを精査し、Makefileを作成しています。
こちらのサイトにソースファイルからビルドする手順と説明が体系的に記載されており、非常に参考になります。
コンパイル (configure) オプションについては、説明を割愛します。Dockerfile内の説明にもありますが、あとから導入が困難なものは基本的に有効化されているようです。
Dockerイメージ 7層目(3/4)
# bundled pcre does not support JIT on s390x # https://manpages.debian.org/stretch/libpcre3-dev/pcrejit.3.en.html#AVAILABILITY_OF_JIT_SUPPORT $(test "$gnuArch" = 's390x-linux-gnu' && echo '--without-pcre-jit') \ \ ${PHP_EXTRA_CONFIGURE_ARGS:-} \ ; \ make -j "$(nproc)"; \ find -type f -name '*.a' -delete; \ make install; \ find /usr/local/bin /usr/local/sbin -type f -perm +0111 -exec strip --strip-all '{}' + || true; \ make clean; \ \ # https://github.com/docker-library/php/issues/692 (copy default example "php.ini" files somewhere easily discoverable) cp -v php.ini-* "$PHP_INI_DIR/"; \ \ cd /; \ docker-php-source delete; \ \ ★続く
140行目: s390xではpcre-jitをサポートしていないようで、s390xの場合には–without-pcre-jitオプションをつけています。
s390xはIBMのCPUアーキテクチャで、pcre-jitはこちらのページがわかりやすいです。
144行目: makeコマンドでMakefileを生成しています。
makeの-jオプションについてはこちらに記載があるように、コンパイル時の並列性を指定できます。この中では、nprocでcpuコア数を取得して引数として与えています。
145行目 : 静的ライブラリ(.a)を削除し、
146行目: make installでビルドしてから、
147行目: シンボルファイルを削除しています。
シンボルファイルについてはこちらがわかりやすいです。
148行目: ビルド時に生成されたファイルを削除
149行目: PHPデフォルトのphp.ini-development, php.ini-productionなどのファイルを${PHP_INI_DIR}にコピー
コメントに記載のあるisuueからもわかるように、デフォルトのphp.iniをそのまま使用すると、 display_errors がonのままとなるようで、production環境では望ましくないのではないかという意見から、設定変更が容易になるように、デフォルトの設定ファイルのテンプレートをコピーしているみたいです。ですので、production環境で利用する場合は、設定ファイルをコピーする必要があることに留意します。
154行目: phpのソースを削除するスクリプト を利用して、ソースファイルを削除しています。
Dockerイメージ 7層目(4/4)
runDeps="$( \ scanelf --needed --nobanner --format '%n#p' --recursive /usr/local \ | tr ',' '\n' \ | sort -u \ | awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \ )"; \ apk add --no-cache $runDeps; \ \ apk del --no-network .build-deps; \ \ # update pecl channel definitions https://github.com/docker-library/php/issues/443 pecl update-channels; \ rm -rf /tmp/pear ~/.pearrc; \ # smoke test php --version
156-161行目: phpに依存されており、かつ共有ライブラリを利用するパッケージを変数に設定し、
162行目: apkに引数として渡してインストールしています。
runDeps変数を設定する箇所では、/usr/local配下について、scanelfコマンドを利用して、バイナリファイルを読み込み/整形しています。trコマンドで、カンマ(,)を改行(\n)に変換し、sortコマンドで重複行を省いた後、共有ライブラリパス(/usr/local/lib)で実行した結果が正常終了(0)なら次の処理へ(next)、それ以外なら、runDeps変数に設定という処理になっています。
scanelfコマンドのmanページはこちらに、elfについてはこちらに、
awkコマンドについてはこちら、awkコマンドで利用するsystem関数はこちらに記載があります。
164行目: ビルド時に利用したパッケージを削除します。
167-168行目: peclのアップデートを実施します。
peclについては、こちらがわかりやすいです。issueでは、ビルド時にはエラーが出ていなかったが、ビルド後にpeclアップデートしてねのwarnigが出たので入れたよ(超意訳)的なことが書いてあります。
170行目: php –versionコマンドで動作することを確認しています。
ディスカッション
コメント一覧
まだ、コメントがありません