Skip to content
Open
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
4 changes: 4 additions & 0 deletions .github/workflows/test_and_publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ jobs:
with:
context: php/${{ matrix.php }}
tags: easyengine/php${{ steps.img-tag.outputs.tag }}:test
secrets: |
github_token=${{ secrets.GITHUB_TOKEN }}

- name: Build and push PHP - ${{ matrix.php }} image
uses: docker/build-push-action@v7
Expand All @@ -62,6 +64,8 @@ jobs:
context: php/${{ matrix.php }}
push: true
tags: easyengine/php${{ steps.img-tag.outputs.tag }}:${{ steps.tag.outputs.tag }}
secrets: |
github_token=${{ secrets.GITHUB_TOKEN }}

other-images: #----------------------------------------------------------------------

Expand Down
61 changes: 50 additions & 11 deletions php/8.1/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,35 @@ RUN curl -fsSL https://packages.sury.org/php/README.txt | bash && \
apt-get update && \
apt-get install -y libc-client-dev

RUN pecl install imagick; \
pecl install memcached; \
pecl install redis; \
pecl install apcu; \
# https://github.com/php/pecl-encryption-mcrypt/issues/7#issuecomment-1050994596
pecl install -n mcrypt; \
pecl install gmagick-2.0.6RC1; \
pecl install timezonedb; \
# Extensions are built with PIE from Packagist/GitHub (not pecl.php.net); docker-php-ext-enable below enables them.
# CI passes its GITHUB_TOKEN as the optional `github_token` BuildKit secret for PIE's GitHub downloads; it never lands in a layer.
RUN --mount=type=secret,id=github_token \
set -eu; \
if [ -s /run/secrets/github_token ]; then \
COMPOSER_AUTH="{\"github-oauth\":{\"github.com\":\"$(cat /run/secrets/github_token)\"}}"; \
export COMPOSER_AUTH; \
fi; \
set -x; \
curl -fsSL -o /usr/local/bin/pie https://github.com/php/pie/releases/download/1.5.2/pie.phar; \
echo "fe70c59738cf56ec00a818cf9cb9593da171aac86f5f1f859995b8839dfd2cc7 /usr/local/bin/pie" | sha256sum -c -; \
chmod +x /usr/local/bin/pie; \
pie install --no-interaction --skip-enable-extension imagick/imagick:3.8.1; \
pie install --no-interaction --skip-enable-extension php-memcached/php-memcached:3.4.0; \
pie install --no-interaction --skip-enable-extension phpredis/phpredis:6.3.0; \
pie install --no-interaction --skip-enable-extension apcu/apcu:5.1.28; \
pie install --no-interaction --skip-enable-extension pecl/mcrypt:1.0.9; \
# timezonedb stays unpinned: it only exists to ship newer tz data than PHP bundles, so it takes the latest release
pie install --no-interaction --skip-enable-extension pecl/timezonedb; \
# Record the exact commits PIE installed in the build log
php -r 'foreach (glob("/root/.pie/*/pie.lock") as $f) foreach (json_decode(file_get_contents($f), true)["packages"] as $p) echo "PIE installed ", $p["name"], " ", $p["version"], " ", $p["dist"]["reference"] ?? $p["source"]["reference"] ?? "?", "\n";'; \
rm -rf /usr/local/bin/pie /root/.pie /root/.composer; \
# gmagick isn't on Packagist: build the source of its pecl 2.0.6RC1 release
mkdir /tmp/gmagick; \
curl -fsSL -o /tmp/gmagick.tar.gz https://github.com/vitoc/gmagick/archive/55423eec7715e89ad63334b35debf582b9566756.tar.gz; \
echo "01fd8f0b0c7e92cd73b9165fa3ea4b247beb35bad8f6dda85d65e960607e97b5 /tmp/gmagick.tar.gz" | sha256sum -c -; \
tar -xzf /tmp/gmagick.tar.gz -C /tmp/gmagick --strip-components=1; \
( cd /tmp/gmagick && phpize && ./configure && make -j"$(nproc)" && make install ); \
rm -rf /tmp/gmagick /tmp/gmagick.tar.gz; \
docker-php-ext-configure gd --with-freetype --with-jpeg --with-webp; \
docker-php-ext-configure zip; \
docker-php-ext-install gd; \
Expand Down Expand Up @@ -87,9 +108,8 @@ RUN curl -sSL "https://getcomposer.org/installer" | php \
&& mv composer.phar /usr/local/bin/composer

# Install wp-cli
RUN curl -O "https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar" \
&& chmod +x wp-cli.phar \
&& mv wp-cli.phar /usr/local/bin/wp
RUN curl -fsSLo /usr/local/bin/wp "https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar" \
&& chmod +x /usr/local/bin/wp

# Setup a config file
RUN mkdir -p /etc/wp-cli
Expand Down Expand Up @@ -126,6 +146,25 @@ COPY docker-entrypoint.sh /usr/local/bin/
COPY newrelic.ini /usr/local/etc/php/conf.d/newrelic.ini
COPY newrelic.ini /data/newrelic.ini

# Fail the build on a PHP startup warning or error, a broken php-fpm config, wp or composer, or a missing module.
# The list is the previous image's full `php -m`, so it also catches a module dropped from PHP itself.
RUN set -eu; \
out="$(php -v 2>&1 && php -m 2>&1)"; \
if printf '%s\n' "$out" | grep -qiE 'warning|error|notice|unable to'; then \
echo "Build check failed: PHP printed these startup warnings or errors:" >&2; \
printf '%s\n' "$out" | grep -iE 'warning|error|notice|unable to' >&2; \
exit 1; \
fi; \
php-fpm -t; \
wp --allow-root --version; \
COMPOSER_ALLOW_SUPERUSER=1 composer --version; \
modules="$(php -m | tr '[:upper:] ' '[:lower:]_')"; \
for m in apcu bcmath calendar core ctype curl date dom exif fileinfo filter ftp gd gmagick gmp hash iconv imagick imap intl json libxml mbstring mcrypt memcached mysqli mysqlnd newrelic openssl pcntl pcre pdo pdo_mysql pdo_sqlite phar posix readline redis reflection session shmop simplexml soap sockets sodium spl sqlite3 standard sysvsem sysvshm timezonedb tokenizer xml xmlreader xmlwriter zend_opcache zip zlib; do \
printf '%s\n' "$modules" | grep -qx "$m" || { echo "Build check failed: PHP module $m is missing" >&2; exit 1; }; \
done; \
# The checks above leave root-owned logs that www-data couldn't write at runtime; don't ship them
rm -f /var/log/php/access.log /var/log/php/error.log /var/log/newrelic/php_agent.log

WORKDIR /var/www/htdocs
RUN usermod -s /bin/bash www-data
USER www-data
Expand Down
61 changes: 50 additions & 11 deletions php/8.2/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,35 @@ RUN curl -fsSL https://packages.sury.org/php/README.txt | bash && \
apt-get update && \
apt-get install -y libc-client-dev

RUN pecl install imagick; \
pecl install memcached; \
pecl install redis; \
pecl install apcu; \
# https://github.com/php/pecl-encryption-mcrypt/issues/7#issuecomment-1050994596
pecl install -n mcrypt; \
pecl install gmagick-2.0.6RC1; \
pecl install timezonedb; \
# Extensions are built with PIE from Packagist/GitHub (not pecl.php.net); docker-php-ext-enable below enables them.
# CI passes its GITHUB_TOKEN as the optional `github_token` BuildKit secret for PIE's GitHub downloads; it never lands in a layer.
RUN --mount=type=secret,id=github_token \
set -eu; \
if [ -s /run/secrets/github_token ]; then \
COMPOSER_AUTH="{\"github-oauth\":{\"github.com\":\"$(cat /run/secrets/github_token)\"}}"; \
export COMPOSER_AUTH; \
fi; \
set -x; \
curl -fsSL -o /usr/local/bin/pie https://github.com/php/pie/releases/download/1.5.2/pie.phar; \
echo "fe70c59738cf56ec00a818cf9cb9593da171aac86f5f1f859995b8839dfd2cc7 /usr/local/bin/pie" | sha256sum -c -; \
chmod +x /usr/local/bin/pie; \
pie install --no-interaction --skip-enable-extension imagick/imagick:3.8.1; \
pie install --no-interaction --skip-enable-extension php-memcached/php-memcached:3.4.0; \
pie install --no-interaction --skip-enable-extension phpredis/phpredis:6.3.0; \
pie install --no-interaction --skip-enable-extension apcu/apcu:5.1.28; \
pie install --no-interaction --skip-enable-extension pecl/mcrypt:1.0.9; \
# timezonedb stays unpinned: it only exists to ship newer tz data than PHP bundles, so it takes the latest release
pie install --no-interaction --skip-enable-extension pecl/timezonedb; \
# Record the exact commits PIE installed in the build log
php -r 'foreach (glob("/root/.pie/*/pie.lock") as $f) foreach (json_decode(file_get_contents($f), true)["packages"] as $p) echo "PIE installed ", $p["name"], " ", $p["version"], " ", $p["dist"]["reference"] ?? $p["source"]["reference"] ?? "?", "\n";'; \
rm -rf /usr/local/bin/pie /root/.pie /root/.composer; \
# gmagick isn't on Packagist: build the source of its pecl 2.0.6RC1 release
mkdir /tmp/gmagick; \
curl -fsSL -o /tmp/gmagick.tar.gz https://github.com/vitoc/gmagick/archive/55423eec7715e89ad63334b35debf582b9566756.tar.gz; \
echo "01fd8f0b0c7e92cd73b9165fa3ea4b247beb35bad8f6dda85d65e960607e97b5 /tmp/gmagick.tar.gz" | sha256sum -c -; \
tar -xzf /tmp/gmagick.tar.gz -C /tmp/gmagick --strip-components=1; \
( cd /tmp/gmagick && phpize && ./configure && make -j"$(nproc)" && make install ); \
rm -rf /tmp/gmagick /tmp/gmagick.tar.gz; \
docker-php-ext-configure gd --with-freetype --with-jpeg --with-webp; \
docker-php-ext-configure zip; \
docker-php-ext-install gd; \
Expand Down Expand Up @@ -85,9 +106,8 @@ RUN curl -sSL "https://getcomposer.org/installer" | php \
&& mv composer.phar /usr/local/bin/composer

# Install wp-cli
RUN curl -O "https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar" \
&& chmod +x wp-cli.phar \
&& mv wp-cli.phar /usr/local/bin/wp
RUN curl -fsSLo /usr/local/bin/wp "https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar" \
&& chmod +x /usr/local/bin/wp

# Setup a config file
RUN mkdir -p /etc/wp-cli
Expand Down Expand Up @@ -124,6 +144,25 @@ COPY docker-entrypoint.sh /usr/local/bin/
COPY newrelic.ini /usr/local/etc/php/conf.d/newrelic.ini
COPY newrelic.ini /data/newrelic.ini

# Fail the build on a PHP startup warning or error, a broken php-fpm config, wp or composer, or a missing module.
# The list is the previous image's full `php -m`, so it also catches a module dropped from PHP itself.
RUN set -eu; \
out="$(php -v 2>&1 && php -m 2>&1)"; \
if printf '%s\n' "$out" | grep -qiE 'warning|error|notice|unable to'; then \
echo "Build check failed: PHP printed these startup warnings or errors:" >&2; \
printf '%s\n' "$out" | grep -iE 'warning|error|notice|unable to' >&2; \
exit 1; \
fi; \
php-fpm -t; \
wp --allow-root --version; \
COMPOSER_ALLOW_SUPERUSER=1 composer --version; \
modules="$(php -m | tr '[:upper:] ' '[:lower:]_')"; \
for m in apcu bcmath calendar core ctype curl date dom exif fileinfo filter gd gmagick gmp hash iconv imagick imap intl json libxml mbstring mcrypt memcached mysqli mysqlnd newrelic openssl pcntl pcre pdo pdo_mysql pdo_sqlite phar posix random readline redis reflection session shmop simplexml soap sockets sodium spl sqlite3 standard sysvsem sysvshm timezonedb tokenizer xml xmlreader xmlwriter zend_opcache zip zlib; do \
printf '%s\n' "$modules" | grep -qx "$m" || { echo "Build check failed: PHP module $m is missing" >&2; exit 1; }; \
done; \
# The checks above leave root-owned logs that www-data couldn't write at runtime; don't ship them
rm -f /var/log/php/access.log /var/log/php/error.log /var/log/newrelic/php_agent.log

WORKDIR /var/www/htdocs
RUN usermod -s /bin/bash www-data
USER www-data
Expand Down
81 changes: 51 additions & 30 deletions php/8.3/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,35 @@ RUN curl -fsSL https://packages.sury.org/php/README.txt | bash && \
apt-get update && \
apt-get install -y libc-client-dev

# RUN pecl install imagick; \ # This is not working with PHP 8.3
RUN pecl install memcached; \
pecl install redis; \
pecl install apcu; \
# https://github.com/php/pecl-encryption-mcrypt/issues/7#issuecomment-1050994596
pecl install -n mcrypt; \
pecl install gmagick-2.0.6RC1; \
pecl install timezonedb; \
# Extensions are built with PIE from Packagist/GitHub (not pecl.php.net); docker-php-ext-enable below enables them.
# CI passes its GITHUB_TOKEN as the optional `github_token` BuildKit secret for PIE's GitHub downloads; it never lands in a layer.
RUN --mount=type=secret,id=github_token \
set -eu; \
if [ -s /run/secrets/github_token ]; then \
COMPOSER_AUTH="{\"github-oauth\":{\"github.com\":\"$(cat /run/secrets/github_token)\"}}"; \
export COMPOSER_AUTH; \
fi; \
set -x; \
curl -fsSL -o /usr/local/bin/pie https://github.com/php/pie/releases/download/1.5.2/pie.phar; \
echo "fe70c59738cf56ec00a818cf9cb9593da171aac86f5f1f859995b8839dfd2cc7 /usr/local/bin/pie" | sha256sum -c -; \
chmod +x /usr/local/bin/pie; \
pie install --no-interaction --skip-enable-extension imagick/imagick:3.8.1; \
pie install --no-interaction --skip-enable-extension php-memcached/php-memcached:3.4.0; \
pie install --no-interaction --skip-enable-extension phpredis/phpredis:6.3.0; \
pie install --no-interaction --skip-enable-extension apcu/apcu:5.1.28; \
pie install --no-interaction --skip-enable-extension pecl/mcrypt:1.0.9; \
# timezonedb stays unpinned: it only exists to ship newer tz data than PHP bundles, so it takes the latest release
pie install --no-interaction --skip-enable-extension pecl/timezonedb; \
# Record the exact commits PIE installed in the build log
php -r 'foreach (glob("/root/.pie/*/pie.lock") as $f) foreach (json_decode(file_get_contents($f), true)["packages"] as $p) echo "PIE installed ", $p["name"], " ", $p["version"], " ", $p["dist"]["reference"] ?? $p["source"]["reference"] ?? "?", "\n";'; \
rm -rf /usr/local/bin/pie /root/.pie /root/.composer; \
# gmagick isn't on Packagist: build the source of its pecl 2.0.6RC1 release
mkdir /tmp/gmagick; \
curl -fsSL -o /tmp/gmagick.tar.gz https://github.com/vitoc/gmagick/archive/55423eec7715e89ad63334b35debf582b9566756.tar.gz; \
echo "01fd8f0b0c7e92cd73b9165fa3ea4b247beb35bad8f6dda85d65e960607e97b5 /tmp/gmagick.tar.gz" | sha256sum -c -; \
tar -xzf /tmp/gmagick.tar.gz -C /tmp/gmagick --strip-components=1; \
( cd /tmp/gmagick && phpize && ./configure && make -j"$(nproc)" && make install ); \
rm -rf /tmp/gmagick /tmp/gmagick.tar.gz; \
docker-php-ext-configure gd --with-freetype --with-jpeg --with-webp; \
docker-php-ext-configure zip; \
docker-php-ext-install gd; \
Expand All @@ -63,30 +84,12 @@ RUN pecl install memcached; \
docker-php-ext-install sysvsem; \
docker-php-ext-install sysvshm; \
docker-php-ext-install bcmath; \
docker-php-ext-enable mcrypt redis timezonedb apcu; \
docker-php-ext-enable imagick mcrypt redis timezonedb apcu; \
echo "extension=memcached.so" >> /usr/local/etc/php/conf.d/memcached.ini; \
echo "extension=gmagick.so" >> /usr/local/etc/php/conf.d/gmagick.ini; \
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
rm -rf /var/lib/apt/lists/*;

# Temp workaround for imagick
RUN apt update && apt install -y git --no-install-recommends && \
git clone https://github.com/Imagick/imagick.git --depth 1 /tmp/imagick && \
cd /tmp/imagick && \
git fetch origin master && \
git switch master && \
cd /tmp/imagick && \
phpize && \
./configure && \
make && \
make install && \
docker-php-ext-enable imagick && \
apt remove -y git && \
apt autoremove -y && \
apt clean && \
rm -rf /var/lib/apt/lists/* && \
rm -rf /tmp/imagick

# set recommended PHP.ini settings
# see https://secure.php.net/manual/en/opcache.installation.php
RUN { \
Expand All @@ -103,9 +106,8 @@ RUN curl -sSL "https://getcomposer.org/installer" | php \
&& mv composer.phar /usr/local/bin/composer

# Install wp-cli
RUN curl -O "https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar" \
&& chmod +x wp-cli.phar \
&& mv wp-cli.phar /usr/local/bin/wp
RUN curl -fsSLo /usr/local/bin/wp "https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar" \
&& chmod +x /usr/local/bin/wp

# Setup a config file
RUN mkdir -p /etc/wp-cli
Expand Down Expand Up @@ -142,6 +144,25 @@ COPY docker-entrypoint.sh /usr/local/bin/
COPY newrelic.ini /usr/local/etc/php/conf.d/newrelic.ini
COPY newrelic.ini /data/newrelic.ini

# Fail the build on a PHP startup warning or error, a broken php-fpm config, wp or composer, or a missing module.
# The list is the previous image's full `php -m`, so it also catches a module dropped from PHP itself.
RUN set -eu; \
out="$(php -v 2>&1 && php -m 2>&1)"; \
if printf '%s\n' "$out" | grep -qiE 'warning|error|notice|unable to'; then \
echo "Build check failed: PHP printed these startup warnings or errors:" >&2; \
printf '%s\n' "$out" | grep -iE 'warning|error|notice|unable to' >&2; \
exit 1; \
fi; \
php-fpm -t; \
wp --allow-root --version; \
COMPOSER_ALLOW_SUPERUSER=1 composer --version; \
modules="$(php -m | tr '[:upper:] ' '[:lower:]_')"; \
for m in apcu bcmath calendar core ctype curl date dom exif fileinfo filter gd gmagick gmp hash iconv imagick imap intl json libxml mbstring mcrypt memcached mysqli mysqlnd newrelic openssl pcntl pcre pdo pdo_mysql pdo_sqlite phar posix random readline redis reflection session shmop simplexml soap sockets sodium spl sqlite3 standard sysvsem sysvshm timezonedb tokenizer xml xmlreader xmlwriter zend_opcache zip zlib; do \
printf '%s\n' "$modules" | grep -qx "$m" || { echo "Build check failed: PHP module $m is missing" >&2; exit 1; }; \
done; \
# The checks above leave root-owned logs that www-data couldn't write at runtime; don't ship them
rm -f /var/log/php/access.log /var/log/php/error.log /var/log/newrelic/php_agent.log

WORKDIR /var/www/htdocs
RUN usermod -s /bin/bash www-data
USER www-data
Expand Down
Loading
Loading