Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions bin/php-from-source
Original file line number Diff line number Diff line change
@@ -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 <version> <sha256 of php-<version>.tar.xz>
#
# It is a no-op once the base image is already at or past <version>, 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 <version> <sha256>" >&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
15 changes: 15 additions & 0 deletions fpm/8.3/Dockerfile.apache
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
15 changes: 15 additions & 0 deletions fpm/8.3/Dockerfile.cli
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
15 changes: 15 additions & 0 deletions fpm/8.5/Dockerfile.apache
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
15 changes: 15 additions & 0 deletions fpm/8.5/Dockerfile.cli
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down