From 175aebfc1e73c9c30b7128831d84870c836aec2b Mon Sep 17 00:00:00 2001 From: Jesse Dobbelaere Date: Fri, 11 Aug 2023 21:52:06 +0200 Subject: [PATCH] Add support for PHP 8.2 --- .github/workflows/build-and-push.yml | 4 +- 8.2/Dockerfile | 144 +++++++++++++++++++++++++++ 8.2/blackfire-install.sh | 34 +++++++ 8.2/craft-cms-xdebug.ini | 1 + 8.2/craft-cms.ini | 14 +++ 8.2/dev.Dockerfile | 33 ++++++ Makefile | 35 ++++++- README.md | 36 ++++--- 8 files changed, 282 insertions(+), 19 deletions(-) create mode 100644 8.2/Dockerfile create mode 100644 8.2/blackfire-install.sh create mode 100644 8.2/craft-cms-xdebug.ini create mode 100644 8.2/craft-cms.ini create mode 100644 8.2/dev.Dockerfile diff --git a/.github/workflows/build-and-push.yml b/.github/workflows/build-and-push.yml index 3673c58..e0d6afe 100644 --- a/.github/workflows/build-and-push.yml +++ b/.github/workflows/build-and-push.yml @@ -19,7 +19,7 @@ jobs: strategy: fail-fast: ${{ github.event_name != 'release' }} matrix: - php: ["8.1", "8.0"] + php: ["8.2", "8.1", "8.0"] type: ["php-fpm", "cli"] include: - type: php-fpm @@ -126,7 +126,7 @@ jobs: strategy: fail-fast: ${{ github.event_name != 'release' }} matrix: - php: ["8.1", "8.0"] + php: ["8.2", "8.1", "8.0"] steps: - name: Set env run: | diff --git a/8.2/Dockerfile b/8.2/Dockerfile new file mode 100644 index 0000000..09304b9 --- /dev/null +++ b/8.2/Dockerfile @@ -0,0 +1,144 @@ +ARG PHP_VERSION +ARG PROJECT_TYPE + +FROM alpine:3.13 AS iconv-build +RUN apk upgrade --no-cache \ + && apk add --no-cache gnu-libiconv + +FROM php:${PHP_VERSION}-${PROJECT_TYPE}-alpine3.18 + +# setup general options for environment variables +ARG PHP_MEMORY_LIMIT_ARG="256M" +ENV PHP_MEMORY_LIMIT=${PHP_MEMORY_LIMIT_ARG} +ARG PHP_MAX_EXECUTION_TIME_ARG="120" +ENV PHP_MAX_EXECUTION_TIME=${PHP_MAX_EXECUTION_TIME_ARG} +ARG PHP_UPLOAD_MAX_FILESIZE_ARG="20M" +ENV PHP_UPLOAD_MAX_FILESIZE=${PHP_UPLOAD_MAX_FILESIZE_ARG} +ARG PHP_MAX_INPUT_VARS_ARG="1000" +ENV PHP_MAX_INPUT_VARS=${PHP_MAX_INPUT_VARS_ARG} +ARG PHP_POST_MAX_SIZE_ARG="8M" +ENV PHP_POST_MAX_SIZE=${PHP_POST_MAX_SIZE_ARG} + +# setup opcache for environment variables +ARG PHP_OPCACHE_ENABLE_ARG="1" +ARG PHP_OPCACHE_REVALIDATE_FREQ_ARG="0" +ARG PHP_OPCACHE_VALIDATE_TIMESTAMPS_ARG="0" +ARG PHP_OPCACHE_MAX_ACCELERATED_FILES_ARG="10000" +ARG PHP_OPCACHE_MEMORY_CONSUMPTION_ARG="128" +ARG PHP_OPCACHE_MAX_WASTED_PERCENTAGE_ARG="10" +ARG PHP_OPCACHE_INTERNED_STRINGS_BUFFER_ARG="16" +ARG PHP_OPCACHE_FAST_SHUTDOWN_ARG="1" +ENV PHP_OPCACHE_ENABLE=$PHP_OPCACHE_ENABLE_ARG +ENV PHP_OPCACHE_REVALIDATE_FREQ=$PHP_OPCACHE_REVALIDATE_FREQ_ARG +ENV PHP_OPCACHE_VALIDATE_TIMESTAMPS=$PHP_OPCACHE_VALIDATE_TIMESTAMPS_ARG +ENV PHP_OPCACHE_MAX_ACCELERATED_FILES=$PHP_OPCACHE_MAX_ACCELERATED_FILES_ARG +ENV PHP_OPCACHE_MEMORY_CONSUMPTION=$PHP_OPCACHE_MEMORY_CONSUMPTION_ARG +ENV PHP_OPCACHE_MAX_WASTED_PERCENTAGE=$PHP_OPCACHE_MAX_WASTED_PERCENTAGE_ARG +ENV PHP_OPCACHE_INTERNED_STRINGS_BUFFER=$PHP_OPCACHE_INTERNED_STRINGS_BUFFER_ARG +ENV PHP_OPCACHE_FAST_SHUTDOWN=$PHP_OPCACHE_FAST_SHUTDOWN_ARG + +# MozJPEG +ENV MOZJPEG_VERSION="3.3.1" +ENV MOZJPEG_BUILD_DEPS \ + autoconf \ + automake \ + build-base \ + libtool \ + nasm \ + pkgconf \ + tar + +RUN set -ex \ + && apk upgrade --no-cache \ + && apk add --no-cache --virtual .build-deps \ + $PHPIZE_DEPS \ + $MOZJPEG_BUILD_DEPS \ + freetype-dev \ + icu-dev \ + icu-data-full \ + libwebp-dev \ + imagemagick-dev \ + libjpeg-turbo-dev \ + libpng-dev \ + libxml2-dev \ + libzip-dev \ + postgresql-dev \ + && apk add --no-cache \ + gifsicle \ + imagemagick \ + jpegoptim \ + libjpeg-turbo-utils \ + libwebp-tools \ + optipng \ + pngquant \ + && docker-php-ext-configure gd \ + --with-freetype \ + --with-jpeg \ + --with-webp \ + && docker-php-ext-install -j$(nproc) \ + bcmath \ + gd \ + intl \ + opcache \ + pdo \ + pdo_mysql \ + pdo_pgsql \ + soap \ + zip \ + && pecl install \ + imagick \ + redis \ + && docker-php-ext-enable \ + imagick \ + redis + +# https://github.com/craftcms/docker/issues/16 +COPY --from=iconv-build /usr/lib/preloadable_libiconv.so /usr/lib/preloadable_libiconv.so + +# https://github.com/docker-library/php/issues/1121 +ENV LD_PRELOAD /usr/lib/preloadable_libiconv.so + +# MozJPEG +WORKDIR /tmp +ADD https://github.com/mozilla/mozjpeg/archive/v${MOZJPEG_VERSION}.tar.gz ./ +RUN set -ex \ + && tar -xzf v${MOZJPEG_VERSION}.tar.gz \ + && cd ./mozjpeg-${MOZJPEG_VERSION} \ + && autoreconf -fiv \ + && ./configure --with-jpeg8 \ + && make \ + && make install + +RUN ln -s /opt/mozjpeg/bin/jpegtran /usr/local/bin/mozjpegtran +RUN ln -s /opt/mozjpeg/bin/cjpeg /usr/local/bin/mozcjpeg + +# Cleanup +RUN RUNTIME_DEPS="$(scanelf --needed --nobanner --recursive /usr/local \ + | awk '{ gsub(/,/, "\nso:", $2); print "so:" $2 }' \ + | sort -u \ + | xargs -r apk info --installed \ + | sort -u)" \ + && apk add --no-cache --virtual .runtime-deps $RUNTIME_DEPS \ + && apk del --no-network .build-deps \ + && rm -rf /tmp/* + +# copy custom.ini settings +COPY craft-cms.ini /usr/local/etc/php/conf.d/ + +# copy the blackfire script +COPY blackfire-install.sh /tmp/blackfire-install.sh + +# run the installation script +RUN set -ex && sh /tmp/blackfire-install.sh && rm -rf /tmp/blackfire* + +# make the directories and set permissions +RUN mkdir -p /app + +# set the permissions on the +RUN chown -R www-data:www-data /app + +# set the working directory for convenience +WORKDIR /app + +# run container as the www-data user +USER www-data diff --git a/8.2/blackfire-install.sh b/8.2/blackfire-install.sh new file mode 100644 index 0000000..2827317 --- /dev/null +++ b/8.2/blackfire-install.sh @@ -0,0 +1,34 @@ +readonly version=$(php -r "echo PHP_MAJOR_VERSION.PHP_MINOR_VERSION;") +readonly system_arch=$(uname -m) + +case $system_arch in + "aarch64") + arch_sys="arm64" + ;; + "arm64") + arch_sys="arm64" + ;; + "x86_64") + arch_sys="amd64" + ;; +esac + +readonly local BLACKFIRE_URL=https://blackfire.io/api/v1/releases/probe/php/alpine/$arch_sys/$version +readonly local ext_dir=$(find /usr/local/lib/php/extensions/ -name "no-debug-non-zts-*") +readonly local so_path="${ext_dir}/blackfire.so" +readonly local ext_ini_string="extension=${so_path}" + +# download the probe +curl -A "Docker" -o /tmp/blackfire-probe.tar.gz -D - -L -s $BLACKFIRE_URL + +# create the temp dir +mkdir -p /tmp/blackfire + +# untar the download +tar zxpf /tmp/blackfire-probe.tar.gz -C /tmp/blackfire + +# move the .so file into the so path +cp /tmp/blackfire/blackfire-*.so $so_path + +# load the extension in the ini file +echo "$ext_ini_string" > /usr/local/etc/php/conf.d/ext-blackfire.ini diff --git a/8.2/craft-cms-xdebug.ini b/8.2/craft-cms-xdebug.ini new file mode 100644 index 0000000..8b2ed7e --- /dev/null +++ b/8.2/craft-cms-xdebug.ini @@ -0,0 +1 @@ +xdebug.mode=develop,debug diff --git a/8.2/craft-cms.ini b/8.2/craft-cms.ini new file mode 100644 index 0000000..8444dca --- /dev/null +++ b/8.2/craft-cms.ini @@ -0,0 +1,14 @@ +memory_limit=${PHP_MEMORY_LIMIT} +max_execution_time=${PHP_MAX_EXECUTION_TIME} +upload_max_filesize=${PHP_UPLOAD_MAX_FILESIZE} +max_input_vars=${PHP_MAX_INPUT_VARS} +post_max_size=${PHP_POST_MAX_SIZE} +[opcache] +opcache.enable=${PHP_OPCACHE_ENABLE} +opcache.revalidate_freq=${PHP_OPCACHE_REVALIDATE_FREQ} +opcache.validate_timestamps=${PHP_OPCACHE_VALIDATE_TIMESTAMPS} +opcache.max_accelerated_files=${PHP_OPCACHE_MAX_ACCELERATED_FILES} +opcache.memory_consumption=${PHP_OPCACHE_MEMORY_CONSUMPTION} +opcache.max_wasted_percentage=${PHP_OPCACHE_MAX_WASTED_PERCENTAGE} +opcache.interned_strings_buffer=${PHP_OPCACHE_INTERNED_STRINGS_BUFFER} +opcache.fast_shutdown=${PHP_OPCACHE_FAST_SHUTDOWN} diff --git a/8.2/dev.Dockerfile b/8.2/dev.Dockerfile new file mode 100644 index 0000000..8c65fed --- /dev/null +++ b/8.2/dev.Dockerfile @@ -0,0 +1,33 @@ +ARG PHP_VERSION +ARG PROJECT_TYPE +FROM craftcms/${PROJECT_TYPE}:${PHP_VERSION} + +# disable opcache +ENV PHP_OPCACHE_ENABLE=0 + +USER root + +COPY craft-cms-xdebug.ini /usr/local/etc/php/conf.d/ + +RUN set -ex \ + && apk upgrade --no-cache \ + && apk --no-cache add --virtual .build-deps $PHPIZE_DEPS \ + && apk --no-cache add \ + git \ + mariadb-connector-c \ + mysql-client \ + nodejs \ + npm \ + postgresql-client \ + linux-headers \ + && pecl install xdebug \ + && docker-php-ext-enable xdebug \ + && apk del --no-network .build-deps + +# install composer +RUN set -ex && curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin --filename=composer + +# expose additional ports for node +EXPOSE 3000 3001 + +USER www-data diff --git a/Makefile b/Makefile index 78867f4..2a8a2f5 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,17 @@ .PHONY: build snyk -LOCAL_PHP_VERSION ?= 8.1 +LOCAL_PHP_VERSION ?= 8.2 build: all-cli all-cli-dev all-php-fpm all-php-fpm-dev all-nginx all-nginx-dev snyk: snyk-all-cli snyk-all-cli-dev snyk-all-php-fpm snyk-all-php-fpm-dev snyk-all-nginx snyk-all-nginx-dev all-cli: docker buildx build --load --platform linux/amd64 --builder all-platforms \ - --build-arg PHP_VERSION=8.1 \ + --build-arg PHP_VERSION=8.2 \ + --build-arg PROJECT_TYPE=cli \ + -t craftcms/cli:8.2 8.2 + docker buildx build --load --platform linux/amd64 --builder all-platforms \ + --build-arg PHP_VERSION=8.2 \ --build-arg PROJECT_TYPE=cli \ -t craftcms/cli:8.1 8.1 docker buildx build --load --platform linux/amd64 --builder all-platforms \ @@ -16,6 +20,11 @@ all-cli: -t craftcms/cli:8.0 8.0 all-cli-dev: + docker buildx build --load --platform linux/amd64 --builder all-platforms \ + -f 8.2/dev.Dockerfile \ + --build-arg PHP_VERSION=8.2 \ + --build-arg PROJECT_TYPE=cli \ + -t craftcms/cli:8.2-dev 8.2 docker buildx build --load --platform linux/amd64 --builder all-platforms \ -f 8.1/dev.Dockerfile \ --build-arg PHP_VERSION=8.1 \ @@ -28,6 +37,10 @@ all-cli-dev: -t craftcms/cli:8.0-dev 8.0 all-php-fpm: + docker buildx build --load --platform linux/amd64 --builder all-platforms \ + --build-arg PHP_VERSION=8.2 \ + --build-arg PROJECT_TYPE=fpm \ + -t craftcms/php-fpm:8.2 8.2 docker buildx build --load --platform linux/amd64 --builder all-platforms \ --build-arg PHP_VERSION=8.1 \ --build-arg PROJECT_TYPE=fpm \ @@ -38,6 +51,11 @@ all-php-fpm: -t craftcms/php-fpm:8.0 8.0 all-php-fpm-dev: + docker buildx build --load --platform linux/amd64 --builder all-platforms \ + -f 8.2/dev.Dockerfile \ + --build-arg PHP_VERSION=8.2 \ + --build-arg PROJECT_TYPE=php-fpm \ + -t craftcms/php-fpm:8.2-dev 8.2 docker buildx build --load --platform linux/amd64 --builder all-platforms \ -f 8.1/dev.Dockerfile \ --build-arg PHP_VERSION=8.1 \ @@ -50,6 +68,9 @@ all-php-fpm-dev: -t craftcms/php-fpm:8.0-dev 8.0 all-nginx: + docker buildx build --load --platform linux/amd64 --builder all-platforms \ + --build-arg PHP_VERSION=8.2 \ + -t craftcms/nginx:8.2 nginx docker buildx build --load --platform linux/amd64 --builder all-platforms \ --build-arg PHP_VERSION=8.1 \ -t craftcms/nginx:8.1 nginx @@ -58,6 +79,10 @@ all-nginx: -t craftcms/nginx:8.0 nginx all-nginx-dev: + docker buildx build --load --platform linux/amd64 --builder all-platforms \ + --build-arg PHP_VERSION=8.2 \ + --build-arg NGINX_CONF=dev.default.conf \ + -t craftcms/nginx:8.2-dev nginx docker buildx build --load --platform linux/amd64 --builder all-platforms \ --build-arg PHP_VERSION=8.1 \ --build-arg NGINX_CONF=dev.default.conf \ @@ -127,30 +152,36 @@ snyk-local: snyk-all-cli: snyk container test \ + craftcms/cli:8.2 \ craftcms/cli:8.1 \ craftcms/cli:8.0 snyk-all-cli-dev: snyk container test \ + craftcms/cli:8.2-dev \ craftcms/cli:8.1-dev \ craftcms/cli:8.0-dev snyk-all-php-fpm: snyk container test \ + craftcms/php-fpm:8.2 \ craftcms/php-fpm:8.1 \ craftcms/php-fpm:8.0 snyk-all-php-fpm-dev: snyk container test \ + craftcms/php-fpm:8.2-dev \ craftcms/php-fpm:8.1-dev \ craftcms/php-fpm:8.0-dev snyk-all-nginx: snyk container test \ + craftcms/nginx:8.2 \ craftcms/nginx:8.1 \ craftcms/nginx:8.0 snyk-all-nginx-dev: snyk container test \ + craftcms/nginx:8.2-dev \ craftcms/nginx:8.1-dev \ craftcms/nginx:8.0-dev diff --git a/README.md b/README.md index 89d76ef..ed16fda 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,9 @@ These images are provided as a starting point for your Docker-based Craft CMS de ## Images -There are three main "types" of images provided for different types of applications; `php-fpm`, `nginx`, and `cli`. Each image allows the developer to select a PHP version (e.g. `craftcms/nginx:8.0`). +There are three main "types" of images provided for different types of applications; `php-fpm`, `nginx`, and `cli`. Each image allows the developer to select a PHP version (e.g. `craftcms/nginx:8.2`). -Each image and PHP version also provides a `-dev` variant which has Xdebug installed and is useful for local development (e.g. `craftcms/php-fpm:8.0-dev`), as well as database tools for creating and restoring backups. Images that do not include `-dev` are considered production. +Each image and PHP version also provides a `-dev` variant which has Xdebug installed and is useful for local development (e.g. `craftcms/php-fpm:8.2-dev`), as well as database tools for creating and restoring backups. Images that do not include `-dev` are considered production. > Note: you are not required to use `-dev` images for local development, they are provided with Xdebug and to make debugging easier. @@ -22,8 +22,10 @@ The `php-fpm` image is provided as the base image (and is also used for the `ngi | Image | Use | Environment | Status | | -------------------------- | --- | ------------- | ------ | -| `craftcms/php-fpm:8.1` | web | `production` | RC | -| `craftcms/php-fpm:8.1-dev` | web | `development` | RC | +| `craftcms/php-fpm:8.2` | web | `production` | | +| `craftcms/php-fpm:8.2-dev` | web | `development` | | +| `craftcms/php-fpm:8.1` | web | `production` | | +| `craftcms/php-fpm:8.1-dev` | web | `development` | | | `craftcms/php-fpm:8.0` | web | `production` | | | `craftcms/php-fpm:8.0-dev` | web | `development` | | | `craftcms/php-fpm:7.4` | web | `production` | | @@ -45,8 +47,10 @@ The `nginx` image is used for a typical installation and includes an Nginx serve | Image | Use | Environment | Status | | ------------------------ | --- | ------------- | ------ | -| `craftcms/nginx:8.1` | web | `production` | RC | -| `craftcms/nginx:8.1-dev` | web | `development` | RC | +| `craftcms/nginx:8.2` | web | `production` | | +| `craftcms/nginx:8.2-dev` | web | `development` | | +| `craftcms/nginx:8.1` | web | `production` | | +| `craftcms/nginx:8.1-dev` | web | `development` | | | `craftcms/nginx:8.0` | web | `production` | | | `craftcms/nginx:8.0-dev` | web | `development` | | | `craftcms/nginx:7.4` | web | `production` | | @@ -68,8 +72,10 @@ The image type `cli` which is used to run queues, migrations, etc. and the image | Image | Use | Environment | Status | | ---------------------- | --- | ------------- | ------ | -| `craftcms/cli:8.1` | web | `production` | RC | -| `craftcms/cli:8.1-dev` | web | `development` | RC | +| `craftcms/cli:8.2` | web | `production` | | +| `craftcms/cli:8.2-dev` | web | `development` | | +| `craftcms/cli:8.1` | web | `production` | | +| `craftcms/cli:8.1-dev` | web | `development` | | | `craftcms/cli:8.0` | web | `production` | | | `craftcms/cli:8.0-dev` | web | `development` | | | `craftcms/cli:7.4` | web | `production` | | @@ -96,7 +102,7 @@ COPY composer.json composer.json COPY composer.lock composer.lock RUN composer install --ignore-platform-reqs --no-interaction --prefer-dist -FROM craftcms/php-fpm:8.0 +FROM craftcms/php-fpm:8.2 # the user is `www-data`, so we copy the files using the user and group COPY --chown=www-data:www-data --from=vendor /app/vendor/ /app/vendor/ @@ -114,7 +120,7 @@ COPY composer.json composer.json COPY composer.lock composer.lock RUN composer install --ignore-platform-reqs --no-interaction --prefer-dist -FROM craftcms/nginx:8.0 +FROM craftcms/nginx:8.2 # switch to the root user to install mysql tools USER root @@ -145,7 +151,7 @@ We recommend running Docker locally if you’re shipping your project to a Docke version: "3.6" services: console: - image: craftcms/cli:8.0-dev + image: craftcms/cli:8.2-dev env_file: .env environment: XDEBUG_CONFIG: client_host=host.docker.internal @@ -159,7 +165,7 @@ services: command: php craft queue/listen web: - image: craftcms/nginx:8.0-dev + image: craftcms/nginx:8.2-dev ports: - 8080:8080 env_file: .env @@ -208,10 +214,10 @@ This can be done via environment variable: `XDEBUG_CONFIG=client_host=host.docke ## Installing Extensions -This image is based off the [official Docker PHP FPM image](https://hub.docker.com/_/php) (Alpine Linux). Therefore you can use all of the tools to install PHP extensions. To install an extension, you have to switch to the `root` user. This example switches to the `root` user to install the [`sockets` extension](https://www.php.net/manual/en/book.sockets.php) for PHP 8.0. Note that it switches back to `www-data` after installation: +This image is based off the [official Docker PHP FPM image](https://hub.docker.com/_/php) (Alpine Linux). Therefore you can use all of the tools to install PHP extensions. To install an extension, you have to switch to the `root` user. This example switches to the `root` user to install the [`sockets` extension](https://www.php.net/manual/en/book.sockets.php) for PHP 8.2. Note that it switches back to `www-data` after installation: ```dockerfile -FROM craftcms/php-fpm:8.0 +FROM craftcms/php-fpm:8.2 # switch to the root user USER root @@ -233,7 +239,7 @@ In this example, we’re setting the PHP memory limit to `512M` rather than the version: "3.6" services: php-fpm: - image: craftcms/php-fpm:8.0-dev + image: craftcms/php-fpm:8.2-dev volumes: - .:/app env_file: .env