diff --git a/bin/php-from-source b/bin/php-from-source new file mode 100755 index 0000000..54b50e3 --- /dev/null +++ b/bin/php-from-source @@ -0,0 +1,83 @@ +#!/bin/sh +# Rebuilds PHP from a php.net source release over the official php:* base image. +# +# Used when a security release is out on php.net but the official Docker images +# have not caught up yet. The base image already records everything needed to +# reproduce its own build: the configure flags (php-config), the compiler flags +# (PHP_CFLAGS etc.) and the source tarball (/usr/src/php.tar.xz). This script +# swaps in the new tarball and repeats that build with the same flags. +# +# Usage: php-from-source .tar.xz> +# +# It is a no-op once the base image is already at or past , so the +# pinned values can stay in the Dockerfiles until the next bump or removal. +# +# Must run before any docker-php-ext-install or pecl install: the bundled +# extensions are compiled from /usr/src/php.tar.xz, and pecl extensions must be +# built against the new headers. +# +# Build dependencies the base image purged after its own build must already be +# installed: libargon2-dev libcurl4-openssl-dev libonig-dev libreadline-dev +# libsodium-dev libsqlite3-dev libssl-dev libxml2-dev zlib1g-dev. +set -e + +VERSION="$1" +SHA256="$2" + +if [ -z "$VERSION" ] || [ -z "$SHA256" ]; then + echo "usage: php-from-source " >&2 + exit 1 +fi + +# shellcheck disable=SC2016 # $argv is PHP, not shell +if php -r 'exit(version_compare(PHP_VERSION, $argv[1], ">=") ? 0 : 1);' "$VERSION"; then + echo "Base image already has PHP $(php -r 'echo PHP_VERSION;'), not rebuilding for ${VERSION}" + exit 0 +fi + +echo "Rebuilding PHP $(php -r 'echo PHP_VERSION;') -> ${VERSION} from source" + +cd /usr/src +curl -fsSL -o php.tar.xz.new "https://www.php.net/distributions/php-${VERSION}.tar.xz" +echo "${SHA256} *php.tar.xz.new" | sha256sum -c - +mv php.tar.xz.new php.tar.xz +# The old signature no longer matches; nothing reads it, so drop it rather than +# leave a misleading file behind. +rm -f php.tar.xz.asc + +# php-config prints the original configure line followed by unquoted +# environment assignments (build_alias=..., PHP_UNAME=Linux - Docker, ...). +# Only the flags before build_alias are configure options. +CONFIGURE_OPTIONS="$(php-config --configure-options | sed 's/ build_alias=.*//')" + +export \ + CFLAGS="$PHP_CFLAGS" \ + CPPFLAGS="$PHP_CPPFLAGS" \ + LDFLAGS="$PHP_LDFLAGS" \ + PHP_BUILD_PROVIDER='https://github.com/docker-library/php' \ + PHP_UNAME='Linux - Docker' + +docker-php-source extract +cd /usr/src/php +# shellcheck disable=SC2086 # word splitting of the configure flags is intended +./configure $CONFIGURE_OPTIONS +make -j "$(nproc)" +find . -type f -name '*.a' -delete +make install +find /usr/local -type f -perm '/0111' -exec sh -c 'strip --strip-all "$@" || :' -- '{}' + +make clean +cd / +docker-php-source delete + +# Fail the build rather than ship an image that still runs the old PHP. +INSTALLED="$(php -r 'echo PHP_VERSION;')" +if [ "$INSTALLED" != "$VERSION" ]; then + echo "ERROR: expected PHP ${VERSION} after rebuild, found ${INSTALLED}" >&2 + exit 1 +fi +if command -v php-fpm > /dev/null && ! php-fpm -v | grep -q "PHP ${VERSION} "; then + echo "ERROR: php-fpm does not report PHP ${VERSION}" >&2 + exit 1 +fi + +php -v diff --git a/fpm/8.3/Dockerfile.apache b/fpm/8.3/Dockerfile.apache index 32b6af1..203dd2c 100644 --- a/fpm/8.3/Dockerfile.apache +++ b/fpm/8.3/Dockerfile.apache @@ -48,11 +48,26 @@ RUN apt-get -y update && apt-get -y upgrade && ACCEPT_EULA=Y && apt-get install imagemagick \ ghostscript \ libavif-dev \ + libargon2-dev \ + libcurl4-openssl-dev \ + libreadline-dev \ + libsodium-dev \ + libsqlite3-dev \ libmaxminddb0 \ libmaxminddb-dev && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* +# PHP 8.3.36 fixes CVE-2026-109618 and CVE-2026-109619 (PHP2Shell). Rebuild PHP +# from the php.net source release until the official php:8.3-fpm image +# carries it; php-from-source does nothing once it does. Keep this before +# the extension builds below, which compile against the rebuilt PHP. +ARG PHP_SOURCE_VERSION=8.3.36 +ARG PHP_SOURCE_SHA256=dd54693aa334c5c4d72e9aee96b082c2473750a18a6c1d105789c93a3b1692fd +COPY bin/php-from-source /usr/local/bin/php-from-source +RUN chmod +x /usr/local/bin/php-from-source && \ + php-from-source "$PHP_SOURCE_VERSION" "$PHP_SOURCE_SHA256" + # PHP extensions, separated for QEMU build purposes RUN docker-php-ext-configure gd --with-freetype --with-webp --with-jpeg --with-avif RUN docker-php-ext-install gd diff --git a/fpm/8.3/Dockerfile.cli b/fpm/8.3/Dockerfile.cli index f5dc136..c0385d7 100644 --- a/fpm/8.3/Dockerfile.cli +++ b/fpm/8.3/Dockerfile.cli @@ -47,11 +47,26 @@ RUN apt-get -y update && apt-get -y upgrade && ACCEPT_EULA=Y && apt-get install imagemagick \ ghostscript \ libavif-dev \ + libargon2-dev \ + libcurl4-openssl-dev \ + libreadline-dev \ + libsodium-dev \ + libsqlite3-dev \ libmaxminddb0 \ libmaxminddb-dev && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* +# PHP 8.3.36 fixes CVE-2026-109618 and CVE-2026-109619 (PHP2Shell). Rebuild PHP +# from the php.net source release until the official php:8.3-cli image +# carries it; php-from-source does nothing once it does. Keep this before +# the extension builds below, which compile against the rebuilt PHP. +ARG PHP_SOURCE_VERSION=8.3.36 +ARG PHP_SOURCE_SHA256=dd54693aa334c5c4d72e9aee96b082c2473750a18a6c1d105789c93a3b1692fd +COPY bin/php-from-source /usr/local/bin/php-from-source +RUN chmod +x /usr/local/bin/php-from-source && \ + php-from-source "$PHP_SOURCE_VERSION" "$PHP_SOURCE_SHA256" + # PHP extensions, separated for QEMU build purposes RUN docker-php-ext-configure gd --with-freetype --with-webp --with-jpeg --with-avif RUN docker-php-ext-install gd diff --git a/fpm/8.5/Dockerfile.apache b/fpm/8.5/Dockerfile.apache index 8171b95..f5397e4 100644 --- a/fpm/8.5/Dockerfile.apache +++ b/fpm/8.5/Dockerfile.apache @@ -48,11 +48,26 @@ RUN apt-get -y update && apt-get -y upgrade && ACCEPT_EULA=Y && apt-get install imagemagick \ ghostscript \ libavif-dev \ + libargon2-dev \ + libcurl4-openssl-dev \ + libreadline-dev \ + libsodium-dev \ + libsqlite3-dev \ libmaxminddb0 \ libmaxminddb-dev && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* +# PHP 8.5.12 fixes CVE-2026-109618 and CVE-2026-109619 (PHP2Shell). Rebuild PHP +# from the php.net source release until the official php:8.5-fpm image +# carries it; php-from-source does nothing once it does. Keep this before +# the extension builds below, which compile against the rebuilt PHP. +ARG PHP_SOURCE_VERSION=8.5.12 +ARG PHP_SOURCE_SHA256=08bc2eba2a588654ade1357174aa646b761556c862dda0678345ee29ed481209 +COPY bin/php-from-source /usr/local/bin/php-from-source +RUN chmod +x /usr/local/bin/php-from-source && \ + php-from-source "$PHP_SOURCE_VERSION" "$PHP_SOURCE_SHA256" + # PHP extensions, separated for QEMU build purposes RUN docker-php-ext-configure gd --with-freetype --with-webp --with-jpeg --with-avif RUN docker-php-ext-install gd diff --git a/fpm/8.5/Dockerfile.cli b/fpm/8.5/Dockerfile.cli index 3a17b2a..2b7f4a2 100644 --- a/fpm/8.5/Dockerfile.cli +++ b/fpm/8.5/Dockerfile.cli @@ -47,11 +47,26 @@ RUN apt-get -y update && apt-get -y upgrade && ACCEPT_EULA=Y && apt-get install imagemagick \ ghostscript \ libavif-dev \ + libargon2-dev \ + libcurl4-openssl-dev \ + libreadline-dev \ + libsodium-dev \ + libsqlite3-dev \ libmaxminddb0 \ libmaxminddb-dev && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* +# PHP 8.5.12 fixes CVE-2026-109618 and CVE-2026-109619 (PHP2Shell). Rebuild PHP +# from the php.net source release until the official php:8.5-cli image +# carries it; php-from-source does nothing once it does. Keep this before +# the extension builds below, which compile against the rebuilt PHP. +ARG PHP_SOURCE_VERSION=8.5.12 +ARG PHP_SOURCE_SHA256=08bc2eba2a588654ade1357174aa646b761556c862dda0678345ee29ed481209 +COPY bin/php-from-source /usr/local/bin/php-from-source +RUN chmod +x /usr/local/bin/php-from-source && \ + php-from-source "$PHP_SOURCE_VERSION" "$PHP_SOURCE_SHA256" + # PHP extensions, separated for QEMU build purposes RUN docker-php-ext-configure gd --with-freetype --with-webp --with-jpeg --with-avif RUN docker-php-ext-install gd