Dockerfileリーディング PHP-FPM公式イメージ(1)

2019/06/30/

本番運用を想定して、Docker上にWordpressを構築するために公式イメージでどういった設定がされているのか読み解く必要がありました(ブラックボックスのものをそのまま使うわけにはいかない)。まずは、PHP-FPMの公式Dockerfileの内容を確認していきます。

今回は、7.2-fpm-alpineのイメージを読んでいきます。Dockerfileの1行目から順にDockerレイアごとに確認していきます。

Dockerイメージ 1層目

#
# NOTE: THIS DOCKERFILE IS GENERATED VIA "update.sh"
#
# PLEASE DO NOT EDIT IT DIRECTLY.
#

FROM alpine:3.10

ベースイメージとして、alpine:3.10が利用されていることがわかります。
alpineの公式イメージ上では、latestとなっていることから最新のalpineバージョンが利用されています。

Dockerイメージ 環境設定1

# dependencies required for running "phpize"
# these get automatically installed and removed by "docker-php-ext-*" (unless they're already installed)
ENV PHPIZE_DEPS \
		autoconf \
		dpkg-dev dpkg \
		file \
		g++ \
		gcc \
		libc-dev \
		make \
		pkgconf \
		re2c

8、9行目の説明にもあるように、phpizeを実行するために必要なパッケージを定義しています。

Dockerイメージ 2層目

# persistent / runtime deps
RUN apk add --no-cache \
		ca-certificates \
		curl \
		tar \
		xz \
# https://github.com/docker-library/php/issues/494
		openssl

ランタイムに必要なパッケージをインストールします。
https://github.com/docker-library/php/issues/494 のコメントは、なぜopensslを導入しているかのリマインドのようです。
ベースイメージとしているalpineでは、opensslからlibresslへの移行を推奨していますが、 LibreSSLにおいて php7.2以上だとopenssl_pkey_newのissueがあることからopensslが導入されたままとなっているようです。
issueが解消され次第、コメントは消え、opensslもなくなることでしょう。

Dockerイメージ 3層目

# ensure www-data user exists
RUN set -eux; \
	addgroup -g 82 -S www-data; \
	adduser -u 82 -D -S -G www-data www-data
# 82 is the standard uid/gid for "www-data" in Alpine
# https://git.alpinelinux.org/aports/tree/main/apache2/apache2.pre-install?h=3.9-stable
# https://git.alpinelinux.org/aports/tree/main/lighttpd/lighttpd.pre-install?h=3.9-stable
# https://git.alpinelinux.org/aports/tree/main/nginx/nginx.pre-install?h=3.9-stable

起動用のグループ/ユーザを作成しています。

alpineでwww-dataユーザを定義する場合は、uid/gidは82がスタンダードであるとコメントに記載されています。 phpを参照するWEBサーバやアプリケーションにあわせてユーザ/グループを設定する必要があるでしょう。

Dockerイメージ 環境設定2

ENV PHP_INI_DIR /usr/local/etc/php

PHP-FPMの設定ファイルを配置するディレクトリを定義しています。

Dockerイメージ 4層目

RUN set -eux; \
	mkdir -p "$PHP_INI_DIR/conf.d"; \
# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743)
	[ ! -d /var/www/html ]; \
	mkdir -p /var/www/html; \
	chown www-data:www-data /var/www/html; \
	chmod 777 /var/www/html

PHP-FPMの設定ファイルを配置するディレクトリを作成し、Apacheのドキュメントルート用のディレクトリを作成しています。

https://github.com/docker-library/php/issues/743に紐付けられているhttps://github.com/docker-library/php/pull/787に記載されていますが、wordpressのapache無しイメージを一般ユーザで利用した際に、Apacheのルートディレクトリの権限の問題でwordpress:fpmのビルドが失敗していたようです。イメージの一貫性を持たせるために、Apache無し版の本イメージにもApacheのドキュメントルート用のディレクトリが作成されています。

Dockerイメージ 環境設定3

##<autogenerated>##
ENV PHP_EXTRA_CONFIGURE_ARGS --enable-fpm --with-fpm-user=www-data --with-fpm-group=www-data --disable-cgi
##</autogenerated>##

PHP-FPMの追加設定用の引数が設定されています。

autogeneratedと記載がありますので、update.shスクリプトから自動生成されたコードかと思われます。

Dockerイメージ 環境設定4

# Apply stack smash protection to functions using local buffers and alloca()
# Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64)
# Enable optimization (-O2)
# Enable linker optimization (this sorts the hash buckets to improve cache locality, and is non-default)
# Adds GNU HASH segments to generated executables (this is used if present, and is much faster than sysv hash; in this configuration, sysv hash is also generated)
# https://github.com/docker-library/php/issues/272
ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2"
ENV PHP_CPPFLAGS="$PHP_CFLAGS"
ENV PHP_LDFLAGS="-Wl,-O1 -Wl,--hash-style=both -pie"

stack smash smash protectionの設定など、PHP-FPMをコンパイルする際のオプションを指定しています。

設定内容は、コメント部分を参照する。経緯はhttps://github.com/docker-library/php/issues/272にまとまっています。

Dockerイメージ 5層目

ENV GPG_KEYS 1729F83938DA44E27BA0F4D3DBDB397470D12172 B1B44D8F021E4E2D6021E995DC9FF8D3EE5AF27F

ENV PHP_VERSION 7.2.19
ENV PHP_URL="https://www.php.net/get/php-7.2.19.tar.xz/from/this/mirror" PHP_ASC_URL="https://www.php.net/get/php-7.2.19.tar.xz.asc/from/this/mirror"
ENV PHP_SHA256="4ffa2404a88d60e993a9fe69f829ebec3eb1e006de41b6048ce5e91bbeaa9282" PHP_MD5=""

RUN set -eux; \
	\
	apk add --no-cache --virtual .fetch-deps gnupg; \
	\
	mkdir -p /usr/src; \
	cd /usr/src; \
	\
	curl -fsSL -o php.tar.xz "$PHP_URL"; \
	\
	if [ -n "$PHP_SHA256" ]; then \
		echo "$PHP_SHA256 *php.tar.xz" | sha256sum -c -; \
	fi; \
	if [ -n "$PHP_MD5" ]; then \
		echo "$PHP_MD5 *php.tar.xz" | md5sum -c -; \
	fi; \
	\
	if [ -n "$PHP_ASC_URL" ]; then \
		curl -fsSL -o php.tar.xz.asc "$PHP_ASC_URL"; \
		export GNUPGHOME="$(mktemp -d)"; \
		for key in $GPG_KEYS; do \
			gpg --batch --keyserver ha.pool.sks-keyservers.net --recv-keys "$key"; \
		done; \
		gpg --batch --verify php.tar.xz.asc php.tar.xz; \
		gpgconf --kill all; \
		rm -rf "$GNUPGHOME"; \
	fi; \
	\
	apk del --no-network .fetch-deps

PHPのソースファイルをダウンロードし、GPGKEYを利用して公開鍵を取得し、パッケージが改ざんされていないことをチェックしています。パッケージチェック後は、gnupgが不要になるため最後に削除しています。