From 6ddaf4a64cba46578d2fc7e5bafcb5d45cc9fa55 Mon Sep 17 00:00:00 2001 From: Jose Quintana Date: Tue, 17 Dec 2024 23:27:49 +0100 Subject: [PATCH 1/3] v8.4.1 --- 8.4-fpm/Dockerfile | 422 +++++++++++++++++++++++++++++++++++ 8.4-fpm/entrypoint.sh | 83 +++++++ 8.4-fpm/envsubst.sh | 45 ++++ 8.4-fpm/extensions.txt | 44 ++++ 8.4-fpm/php-fpm.tmpl.conf | 145 ++++++++++++ 8.4-fpm/php.tmpl.ini | 57 +++++ 8.4-fpm/php_fpm_test.sh | 50 +++++ 8.4-fpm/www.tmpl.conf | 448 ++++++++++++++++++++++++++++++++++++++ README.md | 120 +++++----- 9 files changed, 1357 insertions(+), 57 deletions(-) create mode 100644 8.4-fpm/Dockerfile create mode 100755 8.4-fpm/entrypoint.sh create mode 100755 8.4-fpm/envsubst.sh create mode 100644 8.4-fpm/extensions.txt create mode 100644 8.4-fpm/php-fpm.tmpl.conf create mode 100644 8.4-fpm/php.tmpl.ini create mode 100755 8.4-fpm/php_fpm_test.sh create mode 100644 8.4-fpm/www.tmpl.conf diff --git a/8.4-fpm/Dockerfile b/8.4-fpm/Dockerfile new file mode 100644 index 0000000..dcd7d78 --- /dev/null +++ b/8.4-fpm/Dockerfile @@ -0,0 +1,422 @@ +FROM php:8.4.1-fpm-alpine3.20 + +LABEL Maintainer="Jose Quintana " \ + Description="PHP-FPM v8.4 with essential extensions on top of Alpine Linux." + +# Composer - https://getcomposer.org/download/ +ARG COMPOSER_VERSION="2.8.4" +ARG COMPOSER_SUM="c4c4e2e1beab0ea04e0bd042a5dbba9feda1fbf5eda0d36203958edd343c0a8a" + +# Swoole - https://github.com/swoole/swoole-src +ARG SWOOLE_VERSION="6.0.0" + +# # Phalcon - https://github.com/phalcon/cphalcon +# ARG PHALCON_VERSION="5.8.0" + +# # Imagick - https://github.com/Imagick/imagick +# ARG IMAGICK_COMMIT="28f27044e435a2b203e32675e942eb8de620ee58" + +# Install dependencies +RUN set -eux \ + && apk add --no-cache \ + c-client \ + ca-certificates \ + freetds \ + freetype \ + gettext \ + gmp \ + icu-libs \ + imagemagick \ + imap \ + libffi \ + libgmpxx \ + libintl \ + libjpeg-turbo \ + libpng \ + libpq \ + librdkafka \ + libssh2 \ + libstdc++ \ + libtool \ + libxpm \ + libxslt \ + libzip \ + lz4-libs \ + make \ + rabbitmq-c \ + tidyhtml \ + tzdata \ + unixodbc \ + vips \ + yaml \ + zstd-libs \ + && true + +############################################# +### Install and enable PHP extensions +############################################# + +# Development dependencies +RUN set -eux \ + && apk add --no-cache --virtual .build-deps \ + autoconf \ + bzip2-dev \ + cmake \ + curl-dev \ + freetds-dev \ + freetype-dev \ + g++ \ + gcc \ + gettext-dev \ + git \ + gmp-dev \ + icu-dev \ + imagemagick-dev \ + imap-dev \ + krb5-dev \ + libc-dev \ + libjpeg-turbo-dev \ + libpng-dev \ + librdkafka-dev \ + libssh2-dev \ + libwebp-dev \ + libxml2-dev \ + libxpm-dev \ + libxslt-dev \ + libzip-dev \ + lz4-dev \ + openssl-dev \ + pcre-dev \ + pkgconf \ + postgresql-dev \ + rabbitmq-c-dev \ + tidyhtml-dev \ + unixodbc-dev \ + vips-dev \ + yaml-dev \ + zlib-dev \ + zstd-dev \ +\ +# Workaround for rabbitmq linking issue + && ln -s /usr/lib /usr/local/lib64 \ +\ +# Enable ffi if it exists + && set -eux \ + && if [ -f /usr/local/etc/php/conf.d/docker-php-ext-ffi.ini ]; then \ + echo "ffi.enable = 1" >> /usr/local/etc/php/conf.d/docker-php-ext-ffi.ini; \ + fi \ +\ +################################ +# Install PHP extensions +################################ +\ +# Install gd + && ln -s /usr/lib/$(apk --print-arch)-linux-gnu/libXpm.* /usr/lib/ \ + && docker-php-ext-configure gd \ + --enable-gd \ + --with-webp \ + --with-jpeg \ + --with-xpm \ + --with-freetype \ + --enable-gd-jis-conv \ + && docker-php-ext-install -j$(nproc) gd \ + && true \ +\ +# Install amqp + && pecl install amqp \ + && docker-php-ext-enable amqp \ + && true \ +\ +# Install apcu + && pecl install apcu \ + && docker-php-ext-enable apcu \ + && true \ +\ +# Install gettext + && docker-php-ext-install -j$(nproc) gettext \ + && true \ +\ +# Install gmp + && docker-php-ext-install -j$(nproc) gmp \ + && true \ +\ +# Install bcmath + && docker-php-ext-install -j$(nproc) bcmath \ + && true \ +\ +# Install bz2 + && docker-php-ext-install -j$(nproc) bz2 \ + && true \ +\ +# Install exif + && docker-php-ext-install -j$(nproc) exif \ + && true \ +\ +# Install imap + && docker-php-ext-configure imap --with-kerberos --with-imap-ssl --with-imap \ + && docker-php-ext-install -j$(nproc) imap \ + && true \ +\ +# # Install imagick from source (temporarily) +# && mkdir -p /opt/imagick \ +# && cd /opt/imagick \ +# && git init \ +# && git remote add origin https://github.com/Imagick/imagick.git \ +# && git fetch origin ${IMAGICK_COMMIT} \ +# && git checkout ${IMAGICK_COMMIT} \ +# && phpize && ./configure \ +# && make -j$(nproc) \ +# && make -j$(nproc) install \ +# && docker-php-ext-enable imagick \ +# && true \ +\ +# Install igbinary + && pecl install igbinary \ + && docker-php-ext-enable igbinary \ +\ +# Install intl + && docker-php-ext-install -j$(nproc) intl \ + && true \ +\ +# Install lz4 + && git clone https://github.com/kjdev/php-ext-lz4 /opt/lz4 \ + && cd /opt/lz4 \ + && git checkout $(git tag | grep -E '^[.0-9]+$' | sort -V | tail -1) \ + && phpize \ + && ./configure --enable-lz4 --with-lz4-includedir=/usr \ + && make -j$(nproc) \ + && make install \ + && docker-php-ext-enable lz4 \ + && true \ +\ +# Install memcache + && pecl install memcache \ + && docker-php-ext-enable memcache \ + && true \ +\ +# Install mongodb + && pecl install mongodb \ + && docker-php-ext-enable mongodb \ + && true \ +\ +# Install msgpack + && pecl install msgpack \ + && docker-php-ext-enable msgpack \ + && true \ +\ +# Install mysqli + && docker-php-ext-install -j$(nproc) mysqli \ + && true \ +\ +# Install oauth + && pecl install oauth \ + && docker-php-ext-enable oauth \ + && true \ +\ +# Install opcache + && docker-php-ext-install -j$(nproc) opcache \ + && true \ +\ +# Install pdo_mysql + && docker-php-ext-configure pdo_mysql --with-zlib-dir=/usr \ + && docker-php-ext-install -j$(nproc) pdo_mysql \ + && true \ +\ +# Install pdo_dblib + && docker-php-ext-install -j$(nproc) pdo_dblib \ + && true \ +\ +# Install pcntl + && docker-php-ext-install -j$(nproc) pcntl \ + && true \ +\ +# # Install phalcon +# && git clone --depth=1 --branch=v${PHALCON_VERSION} https://github.com/phalcon/cphalcon.git /opt/phalcon \ +# && cd /opt/phalcon/build \ +# && sh ./install \ +# && docker-php-ext-enable phalcon \ +# && true \ +# \ +# Install pdo_pgsql + && docker-php-ext-install -j$(nproc) pdo_pgsql \ + && true \ +\ +# Install pgsql + && docker-php-ext-install -j$(nproc) pgsql \ + && true \ +\ +# ONLY 64-bit targets + && if [ "$(uname -m)" = "x86_64" ] || [ "$(uname -m)" = "aarch64" ]; then \ + # Install sqlsrv + pecl install sqlsrv; \ + docker-php-ext-enable sqlsrv; \ + true; \ + # Install pdo_sqlsrv + pecl install pdo_sqlsrv; \ + docker-php-ext-enable pdo_sqlsrv; \ + true; \ + fi \ +\ +# Install psr + && pecl install psr \ + && docker-php-ext-enable psr \ + && true \ +\ +# Install redis + && pecl install --configureoptions \ + 'enable-redis-igbinary="yes" enable-redis-zstd="yes" enable-redis-msgpack="yes" enable-redis-lz4="yes"' \ + redis \ + && docker-php-ext-enable redis \ + && true \ +\ +# Install rdkafka + && pecl install rdkafka \ + && docker-php-ext-enable rdkafka \ + && true \ +\ +# Install soap + && docker-php-ext-install -j$(nproc) soap \ + && true \ +\ +# Install ssh2 + && pecl install ssh2-1.3.1 \ + && docker-php-ext-enable ssh2 \ + && true \ +\ +# Install sockets, sysvmsg, sysvsem, sysvshm (also needed by swoole) + && CFLAGS="${CFLAGS:=} -D_GNU_SOURCE" docker-php-ext-install -j$(nproc) \ + sockets \ + sysvmsg \ + sysvsem \ + sysvshm \ + && docker-php-source extract \ + && true \ +\ +# Install swoole (64-bit targets only) +# https://github.com/swoole/swoole-src/issues/5158 + && if [ "$(uname -m)" = "x86_64" ] || [ "$(uname -m)" = "aarch64" ]; then \ + mkdir /usr/src/php/ext/swoole; \ + curl -Lo swoole.tar.gz https://github.com/swoole/swoole-src/archive/v${SWOOLE_VERSION}.tar.gz; \ + tar xfz swoole.tar.gz --strip-components=1 -C /usr/src/php/ext/swoole; \ + docker-php-ext-configure swoole \ + --enable-mysqlnd \ + --enable-sockets \ + --enable-openssl \ + --enable-swoole-curl; \ + docker-php-ext-install -j$(nproc) swoole; \ + rm -rf swoole.tar.gz $HOME/.composer/*-old.phar; \ + docker-php-ext-enable swoole; \ + true; \ + fi \ +\ +# Install tidy + && docker-php-ext-install -j$(nproc) tidy \ + && true \ +\ +# Install uuid + && pecl install uuid \ + && docker-php-ext-enable uuid \ + && true \ +\ +# Install xsl + && docker-php-ext-install -j$(nproc) xsl \ + && true \ +\ +# Install xdebug + && pecl install xdebug \ + && docker-php-ext-enable xdebug \ + && true \ +\ +# Install yaml + && pecl install yaml \ + && docker-php-ext-enable yaml \ + && true \ +\ +# Install vips + && pecl install vips \ + && docker-php-ext-enable vips \ + && true \ +\ +# Install zip + && docker-php-ext-configure zip --with-zip \ + && docker-php-ext-install -j$(nproc) zip \ + && true \ +\ +# Install zstd + && pecl install zstd \ + && docker-php-ext-enable zstd \ + && true \ +\ +# Clean up build packages + && docker-php-source delete \ + && apk del .build-deps \ + && rm -rf /tmp/* \ + && true + +RUN set -eux \ +# Fix php.ini settings for enabled extensions + && chmod +x "$(php -r 'echo ini_get("extension_dir");')"/* \ +# Shrink binaries + && (find /usr/local/bin -type f -print0 | xargs -n1 -0 strip --strip-all -p 2>/dev/null || true) \ + && (find /usr/local/lib -type f -print0 | xargs -n1 -0 strip --strip-all -p 2>/dev/null || true) \ + && (find /usr/local/sbin -type f -print0 | xargs -n1 -0 strip --strip-all -p 2>/dev/null || true) \ + && true + +# Install Composer +RUN set -eux \ + && curl -LO "https://getcomposer.org/download/${COMPOSER_VERSION}/composer.phar" \ + && echo "${COMPOSER_SUM} composer.phar" | sha256sum -c - \ + && chmod +x composer.phar \ + && mv composer.phar /usr/local/bin/composer \ + && composer --version \ + && true + +# Copy PHP-FPM configuration files +COPY 8.4-fpm/php-fpm.tmpl.conf /var/data/php-fpm/php-fpm.tmpl.conf +COPY 8.4-fpm/www.tmpl.conf /var/data/php-fpm/www.tmpl.conf +COPY 8.4-fpm/php.tmpl.ini /var/data/php-fpm/default-php.tmpl.ini + +RUN set -eux \ +# PHP-FPM templates directory + && mkdir -p /var/data/php-fpm \ +# Remove few PHP-FPM default config files + && rm -rf /usr/local/etc/php-fpm.d/zz-docker.conf \ + && rm -rf /usr/local/etc/php-fpm.d/docker.conf \ +\ +# Perform PHP-FPM testing + && echo "Performing PHP-FPM tests..." \ + && echo "date.timezone=UTC" > /usr/local/etc/php/php.ini \ + && php -v | grep -oE 'PHP\s[.0-9]+' | grep -oE '[.0-9]+' | grep '^8.4' \ + && /usr/local/sbin/php-fpm --test \ +\ + && PHP_ERROR="$( php -v 2>&1 1>/dev/null )" \ + && if [ -n "${PHP_ERROR}" ]; then echo "${PHP_ERROR}"; false; fi \ + && PHP_ERROR="$( php -i 2>&1 1>/dev/null )" \ + && if [ -n "${PHP_ERROR}" ]; then echo "${PHP_ERROR}"; false; fi \ +\ + && PHP_FPM_ERROR="$( php-fpm -v 2>&1 1>/dev/null )" \ + && if [ -n "${PHP_FPM_ERROR}" ]; then echo "${PHP_FPM_ERROR}"; false; fi \ + && PHP_FPM_ERROR="$( php-fpm -i 2>&1 1>/dev/null )" \ + && if [ -n "${PHP_FPM_ERROR}" ]; then echo "${PHP_FPM_ERROR}"; false; fi \ + && rm -f /usr/local/etc/php/php.ini \ + && true + +# Copy util scripts +COPY 8.4-fpm/envsubst.sh /envsubst.sh +COPY 8.4-fpm/entrypoint.sh /entrypoint.sh + +STOPSIGNAL SIGQUIT + +ENTRYPOINT ["/entrypoint.sh"] + +EXPOSE 9000 +CMD ["php-fpm"] + + +# Metadata +LABEL org.opencontainers.image.vendor="Jose Quintana" \ + org.opencontainers.image.url="https://github.com/joseluisq/alpine-php-fpm" \ + org.opencontainers.image.title="PHP-FPM v8.4 Alpine" \ + org.opencontainers.image.description="PHP-FPM v8.4 with essential extensions on top of Alpine Linux." \ + org.opencontainers.image.version="$PHP_VERSION" \ + org.opencontainers.image.documentation="https://github.com/joseluisq/alpine-php-fpm" diff --git a/8.4-fpm/entrypoint.sh b/8.4-fpm/entrypoint.sh new file mode 100755 index 0000000..f6b68ea --- /dev/null +++ b/8.4-fpm/entrypoint.sh @@ -0,0 +1,83 @@ +#!/bin/sh + +set -e + +# Check if incomming command contains flags. +if [ "${1#-}" != "$1" ]; then + set -- php-fpm "$@" +fi + +# Replace environment variables if `ENV_SUBSTITUTION_ENABLE=true` +if [[ -n "$ENV_SUBSTITUTION_ENABLE" ]] && [[ "$ENV_SUBSTITUTION_ENABLE" = "true" ]]; then + /envsubst.sh +fi + +# Disable PHP extensions on demand +extensions=${PHP_DISABLE_EXTENSIONS//[[:blank:]]/} +extensions=${extensions//,/ } +extensions_count=$(echo $extensions | grep -o " " | wc -l) + +if [[ -n "$extensions" ]]; then extensions_count=$((extensions_count + 1)); fi + +if [[ $extensions_count -gt 0 ]]; then + echo "Disabling $extensions_count extension(s): $(echo $extensions)" + + ext_dir=$(php -r 'echo ini_get("extension_dir");') + for ext in $extensions; do + disabled=0 + + ext_file="$ext_dir/$ext.so" + if [[ -f "$ext_file" ]]; then + mv -f $ext_file "$ext_file.disabled" + disabled=1 + fi + + ext_file_ini=${PHP_INI_DIR}/conf.d/docker-php-ext-$ext.ini + if [[ -f "$ext_file_ini" ]]; then + mv -f $ext_file_ini "$ext_file_ini.disabled" + disabled=1 + fi + + if [[ "$disabled" = 1 ]]; then + echo "OK: '$ext' disabled" + fi + done + + echo "Verifying PHP extensions..." + + php -v + php-fpm --test + + PHP_ERROR="$(php -v 2>&1 1>/dev/null)" + + if [ -n "${PHP_ERROR}" ]; then + echo "${PHP_ERROR}" + false + fi + + PHP_ERROR="$(php -i 2>&1 1>/dev/null)" + + if [ -n "${PHP_ERROR}" ]; then + echo "${PHP_ERROR}" + false + fi + + PHP_FPM_ERROR="$(php-fpm -v 2>&1 1>/dev/null)" + + if [ -n "${PHP_FPM_ERROR}" ]; then + echo "${PHP_FPM_ERROR}" + false + fi + + PHP_FPM_ERROR="$(php-fpm -i 2>&1 1>/dev/null)" + + if [ -n "${PHP_FPM_ERROR}" ]; then + echo "${PHP_FPM_ERROR}" + false + fi + + echo "Tests were successful!" + echo +fi + +exec "$@" diff --git a/8.4-fpm/envsubst.sh b/8.4-fpm/envsubst.sh new file mode 100755 index 0000000..0300189 --- /dev/null +++ b/8.4-fpm/envsubst.sh @@ -0,0 +1,45 @@ +#!/bin/sh + +set -e + +CWD=/var/data/php-fpm + +# 1. PHP-FPM default settings (php-fpm.conf) +XERROR_LOG=/proc/self/fd/2 +XLOG_LEVEL=error + +if [[ -z "$PHP_FPM_ERROR_LOG" ]]; then export PHP_FPM_ERROR_LOG=$XERROR_LOG; fi +if [[ -z "$PHP_FPM_LOG_LEVEL" ]]; then export PHP_FPM_LOG_LEVEL=$XLOG_LEVEL; fi + +envsubst < "$CWD/php-fpm.tmpl.conf" > "/usr/local/etc/php-fpm.conf" + +# 2. PHP-FPM WWW Pool (www.conf) +XUSER=www-data +XGROUP=www-data +XLISTEN=9000 +XLISTEN_OWNER=$XUSER +XLISTEN_GROUP=$XGROUP + +if [[ -z "$PHP_FPM_LISTEN" ]]; then export PHP_FPM_LISTEN=$XLISTEN; fi +if [[ -z "$PHP_FPM_USER" ]]; then export PHP_FPM_USER=$XUSER; fi +if [[ -z "$PHP_FPM_GROUP" ]]; then export PHP_FPM_GROUP=$XGROUP; fi +if [[ -z "$PHP_FPM_LISTEN_OWNER" ]]; then export PHP_FPM_LISTEN_OWNER=$XLISTEN_OWNER; fi +if [[ -z "$PHP_FPM_LISTEN_GROUP" ]]; then export PHP_FPM_LISTEN_GROUP=$XLISTEN_GROUP; fi + +envsubst < "$CWD/www.tmpl.conf" > "/usr/local/etc/php-fpm.d/www.conf" + +# 3. PHP default settings (default-php.ini) +# 3.1 [PHP] +XMEMORY_LIMIT=512M +XEXPOSE_PHP=On +# 3.2 [Session] +XGC_MAXLIFETIME=1440 + +if [[ -z "$PHP_MEMORY_LIMIT" ]]; + then export PHP_MEMORY_LIMIT=$XMEMORY_LIMIT; fi +if [[ -z "$PHP_EXPOSE_PHP" ]]; + then export PHP_EXPOSE_PHP=$XEXPOSE_PHP; fi +if [[ -z "$PHP_SESSION_GC_MAXLIFETIME" ]]; + then export PHP_SESSION_GC_MAXLIFETIME=$XGC_MAXLIFETIME; fi + +envsubst < "$CWD/default-php.tmpl.ini" > "${PHP_INI_DIR}/conf.d/default-php.ini" diff --git a/8.4-fpm/extensions.txt b/8.4-fpm/extensions.txt new file mode 100644 index 0000000..c109893 --- /dev/null +++ b/8.4-fpm/extensions.txt @@ -0,0 +1,44 @@ +amqp +apcu +bcmath +bz2 +exif +gd +gettext +gmp +igbinary +imap +intl +lz4 +memcache +mongodb +msgpack +mysqli +oauth +opcache +pcntl +pdo_dblib +pdo_mysql +pdo_pgsql +pdo_sqlsrv +pgsql +psr +rdkafka +redis +soap +sockets +sodium +sqlsrv +ssh2 +swoole +sysvmsg +sysvsem +sysvshm +tidy +uuid +vips +xdebug +xsl +yaml +zip +zstd diff --git a/8.4-fpm/php-fpm.tmpl.conf b/8.4-fpm/php-fpm.tmpl.conf new file mode 100644 index 0000000..40782f9 --- /dev/null +++ b/8.4-fpm/php-fpm.tmpl.conf @@ -0,0 +1,145 @@ +;;;;;;;;;;;;;;;;;;;;; +; FPM Configuration ; +;;;;;;;;;;;;;;;;;;;;; + +; All relative paths in this configuration file are relative to PHP's install +; prefix (/usr/local). This prefix can be dynamically changed by using the +; '-p' argument from the command line. + +;;;;;;;;;;;;;;;;;; +; Global Options ; +;;;;;;;;;;;;;;;;;; + +[global] +; Pid file +; Note: the default prefix is /usr/local/var +; Default Value: none +;pid = run/php-fpm.pid + +; Error log file +; If it's set to "syslog", log is sent to syslogd instead of being written +; into a local file. +; Note: the default prefix is /usr/local/var +; Default Value: log/php-fpm.log +; For Docker: /proc/self/fd/2 +error_log = $PHP_FPM_ERROR_LOG + +; syslog_facility is used to specify what type of program is logging the +; message. This lets syslogd specify that messages from different facilities +; will be handled differently. +; See syslog(3) for possible values (ex daemon equiv LOG_DAEMON) +; Default Value: daemon +;syslog.facility = daemon + +; syslog_ident is prepended to every message. If you have multiple FPM +; instances running on the same server, you can change the default value +; which must suit common needs. +; Default Value: php-fpm +;syslog.ident = php-fpm + +; Log level +; Possible Values: alert, error, warning, notice, debug +; Default Value: notice +log_level = $PHP_FPM_LOG_LEVEL + +; Log limit on number of characters in the single line (log entry). If the +; line is over the limit, it is wrapped on multiple lines. The limit is for +; all logged characters including message prefix and suffix if present. However +; the new line character does not count into it as it is present only when +; logging to a file descriptor. It means the new line character is not present +; when logging to syslog. +; Default Value: 1024 +; https://github.com/docker-library/php/pull/725#issuecomment-443540114 +log_limit = 8192 + +; Log buffering specifies if the log line is buffered which means that the +; line is written in a single write operation. If the value is false, then the +; data is written directly into the file descriptor. It is an experimental +; option that can potentionaly improve logging performance and memory usage +; for some heavy logging scenarios. This option is ignored if logging to syslog +; as it has to be always buffered. +; Default value: yes +;log_buffering = no + +; If this number of child processes exit with SIGSEGV or SIGBUS within the time +; interval set by emergency_restart_interval then FPM will restart. A value +; of '0' means 'Off'. +; Default Value: 0 +;emergency_restart_threshold = 0 + +; Interval of time used by emergency_restart_interval to determine when +; a graceful restart will be initiated. This can be useful to work around +; accidental corruptions in an accelerator's shared memory. +; Available Units: s(econds), m(inutes), h(ours), or d(ays) +; Default Unit: seconds +; Default Value: 0 +;emergency_restart_interval = 0 + +; Time limit for child processes to wait for a reaction on signals from master. +; Available units: s(econds), m(inutes), h(ours), or d(ays) +; Default Unit: seconds +; Default Value: 0 +;process_control_timeout = 0 + +; The maximum number of processes FPM will fork. This has been designed to control +; the global number of processes when using dynamic PM within a lot of pools. +; Use it with caution. +; Note: A value of 0 indicates no limit +; Default Value: 0 +; process.max = 128 + +; Specify the nice(2) priority to apply to the master process (only if set) +; The value can vary from -19 (highest priority) to 20 (lowest priority) +; Note: - It will only work if the FPM master process is launched as root +; - The pool process will inherit the master process priority +; unless specified otherwise +; Default Value: no set +; process.priority = -19 + +; Send FPM to background. Set to 'no' to keep FPM in foreground for debugging. +; Default Value: yes +daemonize = no + +; Set open file descriptor rlimit for the master process. +; Default Value: system defined value +;rlimit_files = 1024 + +; Set max core size rlimit for the master process. +; Possible Values: 'unlimited' or an integer greater or equal to 0 +; Default Value: system defined value +;rlimit_core = 0 + +; Specify the event mechanism FPM will use. The following is available: +; - select (any POSIX os) +; - poll (any POSIX os) +; - epoll (linux >= 2.5.44) +; - kqueue (FreeBSD >= 4.1, OpenBSD >= 2.9, NetBSD >= 2.0) +; - /dev/poll (Solaris >= 7) +; - port (Solaris >= 10) +; Default Value: not set (auto detection) +;events.mechanism = epoll + +; When FPM is built with systemd integration, specify the interval, +; in seconds, between health report notification to systemd. +; Set to 0 to disable. +; Available Units: s(econds), m(inutes), h(ours) +; Default Unit: seconds +; Default value: 10 +;systemd_interval = 10 + +;;;;;;;;;;;;;;;;;;;; +; Pool Definitions ; +;;;;;;;;;;;;;;;;;;;; + +; Multiple pools of child processes may be started with different listening +; ports and different management options. The name of the pool will be +; used in logs and stats. There is no limitation on the number of pools which +; FPM can handle. Your system will tell you anyway :) + +; Include one or more files. If glob(3) exists, it is used to include a bunch of +; files from a glob(3) pattern. This directive can be used everywhere in the +; file. +; Relative path can also be used. They will be prefixed by: +; - the global prefix if it's been set (-p argument) +; - /usr/local otherwise +include = /usr/local/etc/php-fpm.d/*.conf diff --git a/8.4-fpm/php.tmpl.ini b/8.4-fpm/php.tmpl.ini new file mode 100644 index 0000000..a093cb1 --- /dev/null +++ b/8.4-fpm/php.tmpl.ini @@ -0,0 +1,57 @@ +[PHP] + +; Memory +; Note: "memory_limit" should be larger than "post_max_size" +memory_limit = $PHP_MEMORY_LIMIT + + +; Timeouts +max_execution_time = 120 +max_input_time = 120 + + +; Uploads +; Note: "post_max_size" should be greater than "upload_max_filesize" +post_max_size = 72M +upload_max_filesize = 64M +max_file_uploads = 20 + + +; Vars +variables_order = EGPCS +max_input_vars = 8000 +max_input_nesting_level = 64 + + +; Error reporting +; Note: error_log is dynamic and handled during start to set appropriate setting +error_reporting = E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED +xmlrpc_errors = Off +report_memleaks = On +display_errors = Off +display_startup_errors = Off +log_errors = On +html_errors = Off + + +; Xdebug settings +xdebug.default_enable = Off +xdebug.profiler_enable = Off +xdebug.remote_enable = Off +xdebug.remote_autostart = Off + +; +; Misc +; +; Decides whether PHP may expose the fact that it is installed on the server +; (e.g. by adding its signature to the Web server header). It is no security +; threat in any way, but it makes it possible to determine whether you use PHP +; on your server or not. +; Default: On +expose_php = $PHP_EXPOSE_PHP + +[Session] +; After this number of seconds, stored data will be seen as 'garbage' and +; cleaned up by the garbage collection process. +; http://php.net/session.gc-maxlifetime +session.gc_maxlifetime = $PHP_SESSION_GC_MAXLIFETIME diff --git a/8.4-fpm/php_fpm_test.sh b/8.4-fpm/php_fpm_test.sh new file mode 100755 index 0000000..991983b --- /dev/null +++ b/8.4-fpm/php_fpm_test.sh @@ -0,0 +1,50 @@ +#!/bin/sh + +set -eu + +echo "Testing PHP-FPM configurations and extensions..." +echo + +php -v +echo + +PHP_VERSION=$(php -v | grep -oE 'PHP\s[.0-9]+' | grep -oE '[.0-9]+' | grep '^8.4') + +echo "Using PHP v$PHP_VERSION" +echo + +php-fpm --test + + +echo "Verifying PHP extensions..." +echo + +PHP_ERROR="$(php -v 2>&1 1>/dev/null)" + +if [ -n "${PHP_ERROR}" ]; then + echo "${PHP_ERROR}"; + false; +fi + +PHP_ERROR="$(php -i 2>&1 1>/dev/null)" + +if [ -n "${PHP_ERROR}" ]; then + echo "${PHP_ERROR}"; + false; +fi + +PHP_FPM_ERROR="$(php-fpm -v 2>&1 1>/dev/null)" + +if [ -n "${PHP_FPM_ERROR}" ]; then + echo "${PHP_FPM_ERROR}"; + false; +fi + +PHP_FPM_ERROR="$(php-fpm -i 2>&1 1>/dev/null)" + +if [ -n "${PHP_FPM_ERROR}" ]; then + echo "${PHP_FPM_ERROR}"; + false; +fi + +echo "Tests were successful!" diff --git a/8.4-fpm/www.tmpl.conf b/8.4-fpm/www.tmpl.conf new file mode 100644 index 0000000..94e6b61 --- /dev/null +++ b/8.4-fpm/www.tmpl.conf @@ -0,0 +1,448 @@ +; Start a new pool named 'www'. +; the variable $pool can be used in any directive and will be replaced by the +; pool name ('www' here) +[www] + +; Per pool prefix +; It only applies on the following directives: +; - 'access.log' +; - 'slowlog' +; - 'listen' (unixsocket) +; - 'chroot' +; - 'chdir' +; - 'php_values' +; - 'php_admin_values' +; When not set, the global prefix (or NONE) applies instead. +; Note: This directive can also be relative to the global prefix. +; Default Value: none +;prefix = /path/to/pools/$pool + +; Unix user/group of processes +; Note: The user is mandatory. If the group is not set, the default user's group +; will be used. +user = $PHP_FPM_USER +group = $PHP_FPM_GROUP + +; The address on which to accept FastCGI requests. +; Valid syntaxes are: +; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific IPv4 address on +; a specific port; +; '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on +; a specific port; +; 'port' - to listen on a TCP socket to all addresses +; (IPv6 and IPv4-mapped) on a specific port; +; '/path/to/unix/socket' - to listen on a unix socket. +; Note: This value is mandatory. +listen = $PHP_FPM_LISTEN + +; Set listen(2) backlog. +; Default Value: 511 (-1 on FreeBSD and OpenBSD) +; A maximum of backlog incoming connections will be queued for processing. +; If a connection request arrives with the queue full the client may receive an error with an +; indication of ECONNREFUSED, or, if the underlying protocol supports retransmission, +; the request may be ignored so that retries may succeed. + +; This should not be greater than `cat /proc/sys/net/core/somaxconn`, otherwise connections +; are silently truncated +listen.backlog = 1024 + +; Set permissions for unix socket, if one is used. In Linux, read/write +; permissions must be set in order to allow connections from a web server. Many +; BSD-derived systems allow connections regardless of permissions. +; Default Values: user and group are set as the running user +; mode is set to 0660 +listen.owner = $PHP_FPM_LISTEN_OWNER +listen.group = $PHP_FPM_LISTEN_GROUP +;listen.mode = 0660 +; When POSIX Access Control Lists are supported you can set them using +; these options, value is a comma separated list of user/group names. +; When set, listen.owner and listen.group are ignored +;listen.acl_users = +;listen.acl_groups = + +; List of addresses (IPv4/IPv6) of FastCGI clients which are allowed to connect. +; Equivalent to the FCGI_WEB_SERVER_ADDRS environment variable in the original +; PHP FCGI (5.2.2+). Makes sense only with a tcp listening socket. Each address +; must be separated by a comma. If this value is left blank, connections will be +; accepted from any ip address. +; Default Value: any +;listen.allowed_clients = 127.0.0.1 + +; Specify the nice(2) priority to apply to the pool processes (only if set) +; The value can vary from -19 (highest priority) to 20 (lower priority) +; Note: - It will only work if the FPM master process is launched as root +; - The pool processes will inherit the master process priority +; unless it specified otherwise +; Default Value: no set +; process.priority = -19 + +; Set the process dumpable flag (PR_SET_DUMPABLE prctl) even if the process user +; or group is differrent than the master process user. It allows to create process +; core dump and ptrace the process for the pool user. +; Default Value: no +; process.dumpable = yes + +; Choose how the process manager will control the number of child processes. +; Possible Values: +; static - a fixed number (pm.max_children) of child processes; +; dynamic - the number of child processes are set dynamically based on the +; following directives. With this process management, there will be +; always at least 1 children. +; pm.max_children - the maximum number of children that can +; be alive at the same time. +; pm.start_servers - the number of children created on startup. +; pm.min_spare_servers - the minimum number of children in 'idle' +; state (waiting to process). If the number +; of 'idle' processes is less than this +; number then some children will be created. +; pm.max_spare_servers - the maximum number of children in 'idle' +; state (waiting to process). If the number +; of 'idle' processes is greater than this +; number then some children will be killed. +; ondemand - no children are created at startup. Children will be forked when +; new requests will connect. The following parameter are used: +; pm.max_children - the maximum number of children that +; can be alive at the same time. +; pm.process_idle_timeout - The number of seconds after which +; an idle process will be killed. +; Note: This value is mandatory. +pm = ondemand + +; The number of child processes to be created when pm is set to 'static' and the +; maximum number of child processes when pm is set to 'dynamic' or 'ondemand'. +; This value sets the limit on the number of simultaneous requests that will be +; served. Equivalent to the ApacheMaxClients directive with mpm_prefork. +; Equivalent to the PHP_FCGI_CHILDREN environment variable in the original PHP +; CGI. The below defaults are based on a server without much resources. Don't +; forget to tweak pm.* to fit your needs. +; Note: Used when pm is set to 'static', 'dynamic' or 'ondemand' +; Note: This value is mandatory. +pm.max_children = 100 + +; The number of child processes created on startup. +; Note: Used only when pm is set to 'dynamic' +; Default Value: (min_spare_servers + max_spare_servers) / 2 +pm.start_servers = 4 + +; The desired minimum number of idle server processes. +; Note: Used only when pm is set to 'dynamic' +; Note: Mandatory when pm is set to 'dynamic' +pm.min_spare_servers = 2 + +; The desired maximum number of idle server processes. +; Note: Used only when pm is set to 'dynamic' +; Note: Mandatory when pm is set to 'dynamic' +pm.max_spare_servers = 6 + +; The number of seconds after which an idle process will be killed. +; Note: Used only when pm is set to 'ondemand' +; Default Value: 10s +;pm.process_idle_timeout = 10s + +; The number of requests each child process should execute before respawning. +; This can be useful to work around memory leaks in 3rd party libraries. For +; endless request processing specify '0'. Equivalent to PHP_FCGI_MAX_REQUESTS. +; Default Value: 0 +pm.max_requests = 1000 + +; The URI to view the FPM status page. If this value is not set, no URI will be +; recognized as a status page. It shows the following informations: +; pool - the name of the pool; +; process manager - static, dynamic or ondemand; +; start time - the date and time FPM has started; +; start since - number of seconds since FPM has started; +; accepted conn - the number of request accepted by the pool; +; listen queue - the number of request in the queue of pending +; connections (see backlog in listen(2)); +; max listen queue - the maximum number of requests in the queue +; of pending connections since FPM has started; +; listen queue len - the size of the socket queue of pending connections; +; idle processes - the number of idle processes; +; active processes - the number of active processes; +; total processes - the number of idle + active processes; +; max active processes - the maximum number of active processes since FPM +; has started; +; max children reached - number of times, the process limit has been reached, +; when pm tries to start more children (works only for +; pm 'dynamic' and 'ondemand'); +; Value are updated in real time. +; Example output: +; pool: www +; process manager: static +; start time: 01/Jul/2011:17:53:49 +0200 +; start since: 62636 +; accepted conn: 190460 +; listen queue: 0 +; max listen queue: 1 +; listen queue len: 42 +; idle processes: 4 +; active processes: 11 +; total processes: 15 +; max active processes: 12 +; max children reached: 0 +; +; By default the status page output is formatted as text/plain. Passing either +; 'html', 'xml' or 'json' in the query string will return the corresponding +; output syntax. Example: +; http://www.foo.bar/status +; http://www.foo.bar/status?json +; http://www.foo.bar/status?html +; http://www.foo.bar/status?xml +; +; By default the status page only outputs short status. Passing 'full' in the +; query string will also return status for each pool process. +; Example: +; http://www.foo.bar/status?full +; http://www.foo.bar/status?json&full +; http://www.foo.bar/status?html&full +; http://www.foo.bar/status?xml&full +; The Full status returns for each process: +; pid - the PID of the process; +; state - the state of the process (Idle, Running, ...); +; start time - the date and time the process has started; +; start since - the number of seconds since the process has started; +; requests - the number of requests the process has served; +; request duration - the duration in ยตs of the requests; +; request method - the request method (GET, POST, ...); +; request URI - the request URI with the query string; +; content length - the content length of the request (only with POST); +; user - the user (PHP_AUTH_USER) (or '-' if not set); +; script - the main script called (or '-' if not set); +; last request cpu - the %cpu the last request consumed +; it's always 0 if the process is not in Idle state +; because CPU calculation is done when the request +; processing has terminated; +; last request memory - the max amount of memory the last request consumed +; it's always 0 if the process is not in Idle state +; because memory calculation is done when the request +; processing has terminated; +; If the process is in Idle state, then informations are related to the +; last request the process has served. Otherwise informations are related to +; the current request being served. +; Example output: +; ************************ +; pid: 31330 +; state: Running +; start time: 01/Jul/2011:17:53:49 +0200 +; start since: 63087 +; requests: 12808 +; request duration: 1250261 +; request method: GET +; request URI: /test_mem.php?N=10000 +; content length: 0 +; user: - +; script: /home/fat/web/docs/php/test_mem.php +; last request cpu: 0.00 +; last request memory: 0 +; +; Note: There is a real-time FPM status monitoring sample web page available +; It's available in: /usr/local/share/php/fpm/status.html +; +; Note: The value must start with a leading slash (/). The value can be +; anything, but it may not be a good idea to use the .php extension or it +; may conflict with a real PHP file. +; Default Value: not set +;pm.status_path = /status + +; The ping URI to call the monitoring page of FPM. If this value is not set, no +; URI will be recognized as a ping page. This could be used to test from outside +; that FPM is alive and responding, or to +; - create a graph of FPM availability (rrd or such); +; - remove a server from a group if it is not responding (load balancing); +; - trigger alerts for the operating team (24/7). +; Note: The value must start with a leading slash (/). The value can be +; anything, but it may not be a good idea to use the .php extension or it +; may conflict with a real PHP file. +; Default Value: not set +;ping.path = /ping + +; This directive may be used to customize the response of a ping request. The +; response is formatted as text/plain with a 200 response code. +; Default Value: pong +;ping.response = pong + +; The access log file +; Default: not set +;access.log = log/$pool.access.log +access.log = /proc/self/fd/2 + +; The access log format. +; The following syntax is allowed +; %%: the '%' character +; %C: %CPU used by the request +; it can accept the following format: +; - %{user}C for user CPU only +; - %{system}C for system CPU only +; - %{total}C for user + system CPU (default) +; %d: time taken to serve the request +; it can accept the following format: +; - %{seconds}d (default) +; - %{miliseconds}d +; - %{mili}d +; - %{microseconds}d +; - %{micro}d +; %e: an environment variable (same as $_ENV or $_SERVER) +; it must be associated with embraces to specify the name of the env +; variable. Some exemples: +; - server specifics like: %{REQUEST_METHOD}e or %{SERVER_PROTOCOL}e +; - HTTP headers like: %{HTTP_HOST}e or %{HTTP_USER_AGENT}e +; %f: script filename +; %l: content-length of the request (for POST request only) +; %m: request method +; %M: peak of memory allocated by PHP +; it can accept the following format: +; - %{bytes}M (default) +; - %{kilobytes}M +; - %{kilo}M +; - %{megabytes}M +; - %{mega}M +; %n: pool name +; %o: output header +; it must be associated with embraces to specify the name of the header: +; - %{Content-Type}o +; - %{X-Powered-By}o +; - %{Transfert-Encoding}o +; - .... +; %p: PID of the child that serviced the request +; %P: PID of the parent of the child that serviced the request +; %q: the query string +; %Q: the '?' character if query string exists +; %r: the request URI (without the query string, see %q and %Q) +; %R: remote IP address +; %s: status (response code) +; %t: server time the request was received +; it can accept a strftime(3) format: +; %d/%b/%Y:%H:%M:%S %z (default) +; The strftime(3) format must be encapsuled in a %{}t tag +; e.g. for a ISO8601 formatted timestring, use: %{%Y-%m-%dT%H:%M:%S%z}t +; %T: time the log has been written (the request has finished) +; it can accept a strftime(3) format: +; %d/%b/%Y:%H:%M:%S %z (default) +; The strftime(3) format must be encapsuled in a %{}t tag +; e.g. for a ISO8601 formatted timestring, use: %{%Y-%m-%dT%H:%M:%S%z}t +; %u: remote user +; +; Default: "%R - %u %t \"%m %r\" %s" +;access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%" + +; The log file for slow requests +; Default Value: not set +; Note: slowlog is mandatory if request_slowlog_timeout is set +;slowlog = log/$pool.log.slow + +; The timeout for serving a single request after which a PHP backtrace will be +; dumped to the 'slowlog' file. A value of '0s' means 'off'. +; Available units: s(econds)(default), m(inutes), h(ours), or d(ays) +; Default Value: 0 +;request_slowlog_timeout = 0 + +; Depth of slow log stack trace. +; Default Value: 20 +;request_slowlog_trace_depth = 20 + +; The timeout for serving a single request after which the worker process will +; be killed. This option should be used when the 'max_execution_time' ini option +; does not stop script execution for some reason. A value of '0' means 'off'. +; Available units: s(econds)(default), m(inutes), h(ours), or d(ays) +; Default Value: 0 +request_terminate_timeout = 120s + +; The timeout set by 'request_terminate_timeout' ini option is not engaged after +; application calls 'fastcgi_finish_request' or when application has finished and +; shutdown functions are being called (registered via register_shutdown_function). +; This option will enable timeout limit to be applied unconditionally +; even in such cases. +; Default Value: no +;request_terminate_timeout_track_finished = no + +; Set open file descriptor rlimit. +; Default Value: system defined value +;rlimit_files = 1024 + +; Set max core size rlimit. +; Possible Values: 'unlimited' or an integer greater or equal to 0 +; Default Value: system defined value +;rlimit_core = 0 + +; Chroot to this directory at the start. This value must be defined as an +; absolute path. When this value is not set, chroot is not used. +; Note: you can prefix with '$prefix' to chroot to the pool prefix or one +; of its subdirectories. If the pool prefix is not set, the global prefix +; will be used instead. +; Note: chrooting is a great security feature and should be used whenever +; possible. However, all PHP paths will be relative to the chroot +; (error_log, sessions.save_path, ...). +; Default Value: not set +;chroot = + +; Chdir to this directory at the start. +; Note: relative path can be used. +; Default Value: current directory or / when chroot +;chdir = /var/www + +; Redirect worker stdout and stderr into main error log. If not set, stdout and +; stderr will be redirected to /dev/null according to FastCGI specs. +; Note: on highloaded environement, this can cause some delay in the page +; process time (several ms). +; Default Value: no +catch_workers_output = yes + +; Decorate worker output with prefix and suffix containing information about +; the child that writes to the log and if stdout or stderr is used as well as +; log level and time. This options is used only if catch_workers_output is yes. +; Settings to "no" will output data as written to the stdout or stderr. +; Default value: yes +decorate_workers_output = no + +; Clear environment in FPM workers +; Prevents arbitrary environment variables from reaching FPM worker processes +; by clearing the environment in workers before env vars specified in this +; pool configuration are added. +; Setting to "no" will make all environment variables available to PHP code +; via getenv(), $_ENV and $_SERVER. +; Default Value: yes +; +; No: Keep env variables set by Docker +clear_env = no + +; Limits the extensions of the main script FPM will allow to parse. This can +; prevent configuration mistakes on the web server side. You should only limit +; FPM to .php extensions to prevent malicious users to use other extensions to +; execute php code. +; Note: set an empty value to allow all extensions. +; Default Value: .php +;security.limit_extensions = .php .php3 .php4 .php5 .php7 + +; Pass environment variables like LD_LIBRARY_PATH. All $VARIABLEs are taken from +; the current environment. +; Default Value: clean env +;env[HOSTNAME] = $HOSTNAME +;env[PATH] = /usr/local/bin:/usr/bin:/bin +;env[TMP] = /tmp +;env[TMPDIR] = /tmp +;env[TEMP] = /tmp + +; Additional php.ini defines, specific to this pool of workers. These settings +; overwrite the values previously defined in the php.ini. The directives are the +; same as the PHP SAPI: +; php_value/php_flag - you can set classic ini defines which can +; be overwritten from PHP call 'ini_set'. +; php_admin_value/php_admin_flag - these directives won't be overwritten by +; PHP call 'ini_set' +; For php_*flag, valid values are on, off, 1, 0, true, false, yes or no. + +; Defining 'extension' will load the corresponding shared extension from +; extension_dir. Defining 'disable_functions' or 'disable_classes' will not +; overwrite previously defined php.ini values, but will append the new value +; instead. + +; Note: path INI options can be relative and will be expanded with the prefix +; (pool, global or /usr/local) + +; Default Value: nothing is defined by default except the values in php.ini and +; specified at startup with the -d argument +;php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f www@my.domain.com +;php_flag[display_errors] = off +;php_admin_value[error_log] = /var/log/fpm-php.www.log +;php_admin_flag[log_errors] = on +;php_admin_value[memory_limit] = 32M diff --git a/README.md b/README.md index b2ea788..a0cf7de 100644 --- a/README.md +++ b/README.md @@ -11,11 +11,11 @@

Alpine PHP-FPM

- Lightweight & optimized Multi-Arch Docker Images (x86_64/arm/arm64) for PHP-FPM (PHP 8.1, 8.2, 8.3) with essential extensions on top of latest Alpine Linux. ๐Ÿ˜ + Lightweight & optimized Multi-Arch Docker Images (x86_64/arm/arm64) for PHP-FPM (PHP 8.1, 8.2, 8.3, 8.4) with essential extensions on top of latest Alpine Linux. ๐Ÿ˜

- + @@ -24,9 +24,9 @@ ## Stable versions -| v8.1 | v8.2 | v8.3 | -| -----: | -----: | -----: | -| ![Docker Image 8.1 (tag 8.1 semver)](https://img.shields.io/docker/v/joseluisq/php-fpm/8.1)
![Docker Image Size (tag)](https://img.shields.io/docker/image-size/joseluisq/php-fpm/8.1) | ![Docker Image 8.2 (tag 8.2 semver)](https://img.shields.io/docker/v/joseluisq/php-fpm/8.2)
![Docker Image Size (tag)](https://img.shields.io/docker/image-size/joseluisq/php-fpm/8.2) | ![Docker Image Version (tag latest semver)](https://img.shields.io/docker/v/joseluisq/php-fpm/8.3)
![Docker Image Size (tag)](https://img.shields.io/docker/image-size/joseluisq/php-fpm/8.3) | +| v8.1 | v8.2 | v8.3 | v8.4 | +| -----: | -----: | -----: | -----: | +| ![Docker Image 8.1 (tag 8.1 semver)](https://img.shields.io/docker/v/joseluisq/php-fpm/8.1)
![Docker Image Size (tag)](https://img.shields.io/docker/image-size/joseluisq/php-fpm/8.1) | ![Docker Image 8.2 (tag 8.2 semver)](https://img.shields.io/docker/v/joseluisq/php-fpm/8.2)
![Docker Image Size (tag)](https://img.shields.io/docker/image-size/joseluisq/php-fpm/8.2) | ![Docker Image 8.3 (tag 8.3 semver)](https://img.shields.io/docker/v/joseluisq/php-fpm/8.3)
![Docker Image Size (tag)](https://img.shields.io/docker/image-size/joseluisq/php-fpm/8.3) | ![Docker Image Version (tag latest semver)](https://img.shields.io/docker/v/joseluisq/php-fpm/8.4)
![Docker Image Size (tag)](https://img.shields.io/docker/image-size/joseluisq/php-fpm/8.4) | ### PHP versions support @@ -39,58 +39,58 @@ However, you can still find legacy versions like `7.4.x` or `8.0.x` on [Releases ## Additional extensions -| Extension | v8.1 | v8.2 | v8.3 | -| ---------- | -----: | -----: | -----: | -| amqp | โœ“ | โœ“ | โœ“ | -| apcu | โœ“ | โœ“ | โœ“ | -| bcmath | โœ“ | โœ“ | โœ“ | -| bz2 | โœ“ | โœ“ | โœ“ | -| exif | โœ“ | โœ“ | โœ“ | -| gd | โœ“ | โœ“ | โœ“ | -| gettext | โœ“ | โœ“ | โœ“ | -| gmp | โœ“ | โœ“ | โœ“ | -| imagick | โœ“ | โœ“ | โœ“ | -| igbinary | โœ“ | โœ“ | โœ“ | -| imap | โœ“ | โœ“ | โœ“ | -| intl | โœ“ | โœ“ | โœ“ | -| lz4 | โœ“ | โœ“ | โœ“ | -| memcache | โœ“ | โœ“ | โœ“ | -| mongodb | โœ“ | โœ“ | โœ“ | -| msgpack | โœ“ | โœ“ | โœ“ | -| mysqli | โœ“ | โœ“ | โœ“ | -| oauth | โœ“ | โœ“ | โœ“ | -| opcache | โœ“ | โœ“ | โœ“ | -| pcntl | โœ“ | โœ“ | โœ“ | -| pdo_dblib | โœ“ | โœ“ | โœ“ | -| pdo_mysql | โœ“ | โœ“ | โœ“ | -| pdo_pgsql | โœ“ | โœ“ | โœ“ | -| pdo_sqlsrv | โœ“ (64-bit only) | โœ“ (64-bit only) | โœ“ (64-bit only) | -| pgsql | โœ“ | โœ“ | โœ“ | -| phalcon | โœ“ | โœ“ | โœ“ | -| psr | โœ“ | โœ“ | โœ“ | -| redis | โœ“ | โœ“ | โœ“ | -| rdkafka | โœ“ | โœ“ | โœ“ | -| soap | โœ“ | โœ“ | โœ“ | -| sockets | โœ“ | โœ“ | โœ“ | -| sqlsrv | โœ“ (64-bit only) | โœ“ (64-bit only) | โœ“ (64-bit only) | +| Extension | v8.1 | v8.2 | v8.3 | v8.4 | +| ---------- | -----: | -----: | -----: | -----: | +| amqp | โœ“ | โœ“ | โœ“ | โœ“ | +| apcu | โœ“ | โœ“ | โœ“ | โœ“ | +| bcmath | โœ“ | โœ“ | โœ“ | โœ“ | +| bz2 | โœ“ | โœ“ | โœ“ | โœ“ | +| exif | โœ“ | โœ“ | โœ“ | โœ“ | +| gd | โœ“ | โœ“ | โœ“ | โœ“ | +| gettext | โœ“ | โœ“ | โœ“ | โœ“ | +| gmp | โœ“ | โœ“ | โœ“ | โœ“ | +| imagick | โœ“ | โœ“ | โœ“ | ? | +| igbinary | โœ“ | โœ“ | โœ“ | โœ“ | +| imap | โœ“ | โœ“ | โœ“ | โœ“ | +| intl | โœ“ | โœ“ | โœ“ | โœ“ | +| lz4 | โœ“ | โœ“ | โœ“ | โœ“ | +| memcache | โœ“ | โœ“ | โœ“ | โœ“ | +| mongodb | โœ“ | โœ“ | โœ“ | โœ“ | +| msgpack | โœ“ | โœ“ | โœ“ | โœ“ | +| mysqli | โœ“ | โœ“ | โœ“ | โœ“ | +| oauth | โœ“ | โœ“ | โœ“ | โœ“ | +| opcache | โœ“ | โœ“ | โœ“ | โœ“ | +| pcntl | โœ“ | โœ“ | โœ“ | โœ“ | +| pdo_dblib | โœ“ | โœ“ | โœ“ | โœ“ | +| pdo_mysql | โœ“ | โœ“ | โœ“ | โœ“ | +| pdo_pgsql | โœ“ | โœ“ | โœ“ | โœ“ | +| pdo_sqlsrv | โœ“ (64-bit only) | โœ“ (64-bit only) | โœ“ (64-bit only) | โœ“ (64-bit only) | +| pgsql | โœ“ | โœ“ | โœ“ | โœ“ | +| phalcon | โœ“ | โœ“ | โœ“ | ? | +| psr | โœ“ | โœ“ | โœ“ | โœ“ | +| redis | โœ“ | โœ“ | โœ“ | โœ“ | +| rdkafka | โœ“ | โœ“ | โœ“ | โœ“ | +| soap | โœ“ | โœ“ | โœ“ | โœ“ | +| sockets | โœ“ | โœ“ | โœ“ | โœ“ | +| sqlsrv | โœ“ (64-bit only) | โœ“ (64-bit only) | โœ“ (64-bit only) | โœ“ (64-bit only) | | ssh2 | โœ“ | โœ“ | โœ“ | -| swoole | โœ“ (64-bit only) | โœ“ (64-bit only) | โœ“ (64-bit only) | -| sysvmsg | โœ“ | โœ“ | โœ“ | -| sysvsem | โœ“ | โœ“ | โœ“ | -| sysvshm | โœ“ | โœ“ | โœ“ | -| tidy | โœ“ | โœ“ | โœ“ | -| uuid | โœ“ | โœ“ | โœ“ | -| vips | โœ“ | โœ“ | โœ“ | -| xdebug | โœ“ | โœ“ | โœ“ | -| xsl | โœ“ | โœ“ | โœ“ | -| yaml | โœ“ | โœ“ | โœ“ | -| zip | โœ“ | โœ“ | โœ“ | -| zstd | โœ“ | โœ“ | โœ“ | -|   |   |   |   | -| **Others** | | | | -| composer | v2.7 | v2.8 | v2.8 | -|   |   |   |   | -| **Extensions file** | [8.1-fpm/extensions.txt](8.1-fpm/extensions.txt) | [8.2-fpm/extensions.txt](8.2-fpm/extensions.txt) | [8.3-fpm/extensions.txt](8.3-fpm/extensions.txt) | +| swoole | โœ“ (64-bit only) | โœ“ (64-bit only) | โœ“ (64-bit only) | โœ“ (64-bit only) | +| sysvmsg | โœ“ | โœ“ | โœ“ | โœ“ | +| sysvsem | โœ“ | โœ“ | โœ“ | โœ“ | +| sysvshm | โœ“ | โœ“ | โœ“ | โœ“ | +| tidy | โœ“ | โœ“ | โœ“ | โœ“ | +| uuid | โœ“ | โœ“ | โœ“ | โœ“ | +| vips | โœ“ | โœ“ | โœ“ | โœ“ | +| xdebug | โœ“ | โœ“ | โœ“ | โœ“ | +| xsl | โœ“ | โœ“ | โœ“ | โœ“ | +| yaml | โœ“ | โœ“ | โœ“ | โœ“ | +| zip | โœ“ | โœ“ | โœ“ | โœ“ | +| zstd | โœ“ | โœ“ | โœ“ | โœ“ | +|   |   |   |   |   | +| **Others** | | | | | +| composer | v2.7 | v2.8 | v2.8 | v2.8 | +|   |   |   |   |   | +| **Extensions file** | [8.1-fpm](8.1-fpm) | [8.2-fpm](8.2-fpm) | [8.3-fpm](8.3-fpm/extensions.txt) | [8.4-fpm](8.4-fpm/extensions.txt) | **Footnotes** @@ -102,7 +102,7 @@ However, you can still find legacy versions like `7.4.x` or `8.0.x` on [Releases If you want to know the whole list of the included extensions then type `php -m` as follows. ```sh -docker run --rm joseluisq/php-fpm:8.3 php -m +docker run --rm joseluisq/php-fpm:8.4 php -m ``` Or use `php -i` to get more detailed information. @@ -110,6 +110,8 @@ Or use `php -i` to get more detailed information. ## Usage ```sh +docker pull joseluisq/php-fpm:8.4 +# Or docker pull joseluisq/php-fpm:8.3 # Or docker pull joseluisq/php-fpm:8.2 @@ -122,6 +124,8 @@ docker pull joseluisq/php-fpm:8.1 ### Dockerfile ```Dockerfile +FROM joseluisq/php-fpm:8.4 +# Or FROM joseluisq/php-fpm:8.3 # Or FROM joseluisq/php-fpm:8.2 @@ -134,6 +138,8 @@ FROM joseluisq/php-fpm:8.1 To give a Docker image a quick try, just execute any of those commands and then navigate to [localhost:8088](http://localhost:8088) ```sh +docker run --rm -p 8088:80 joseluisq/php-fpm:8.4 sh -c "echo ' index.php; php -S [::]:80 -t ." +# Or docker run --rm -p 8088:80 joseluisq/php-fpm:8.3 sh -c "echo ' index.php; php -S [::]:80 -t ." # Or docker run --rm -p 8088:80 joseluisq/php-fpm:8.2 sh -c "echo ' index.php; php -S [::]:80 -t ." From beb8b698bf49fd3a427e87fbced380f5bd96b902 Mon Sep 17 00:00:00 2001 From: Jose Quintana Date: Tue, 17 Dec 2024 23:33:58 +0100 Subject: [PATCH 2/3] chore: enable php 8.4 ci workflow --- .github/workflows/devel-8.4.yml | 78 +++++++++++++++++ .github/workflows/release-8.3.yml | 24 +----- .github/workflows/release-8.4.yml | 136 ++++++++++++++++++++++++++++++ 3 files changed, 215 insertions(+), 23 deletions(-) create mode 100644 .github/workflows/devel-8.4.yml create mode 100644 .github/workflows/release-8.4.yml diff --git a/.github/workflows/devel-8.4.yml b/.github/workflows/devel-8.4.yml new file mode 100644 index 0000000..278feaf --- /dev/null +++ b/.github/workflows/devel-8.4.yml @@ -0,0 +1,78 @@ +name: devel-8.4 +on: + pull_request: + branches: + - master + paths: + - 8.4-fpm/** + - .github/workflows/devel-8.4.yml + push: + branches: + - master + paths: + - 8.4-fpm/** + - .github/workflows/devel-8.4.yml + +jobs: + php: + runs-on: ubuntu-22.04 + strategy: + matrix: + build: + - amd64 + - "386" + - arm64 + - armv7 + - armv6 + include: + - build: amd64 + arch: linux/amd64 + - build: "386" + arch: linux/386 + - build: arm64 + arch: linux/arm64 + - build: armv6 + arch: linux/arm/v6 + - build: armv7 + arch: linux/arm/v7 + steps: + - + name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 1 + - + name: Cache Docker layers + uses: actions/cache@v4 + with: + path: /tmp/.buildx-cache + key: 8.4-fpm-${{ matrix.arch }}-buildx-${{ hashFiles('8.4-fpm/**') }} + restore-keys: | + 8.4-fpm-${{ matrix.arch }}-buildx-${{ hashFiles('8.4-fpm/**') }} + 8.4-fpm-${{ matrix.arch }}-buildx- + - + name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - + name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - + name: Build and Test + uses: docker/build-push-action@v5 + with: + push: false + provenance: false + context: . + platforms: ${{ matrix.arch }} + file: 8.4-fpm/Dockerfile + tags: joseluisq/php-fpm:latest + cache-from: type=local,src=/tmp/.buildx-cache + cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max + - + # Temp fix + # https://github.com/docker/build-push-action/issues/252 + # https://github.com/moby/buildkit/issues/1896 + name: Move cache + run: | + rm -rf /tmp/.buildx-cache + mv /tmp/.buildx-cache-new /tmp/.buildx-cache diff --git a/.github/workflows/release-8.3.yml b/.github/workflows/release-8.3.yml index 769e7d9..57f32e8 100644 --- a/.github/workflows/release-8.3.yml +++ b/.github/workflows/release-8.3.yml @@ -42,7 +42,7 @@ jobs: with: images: joseluisq/php-fpm flavor: | - latest=true + latest=false tags: | type=semver,pattern={{major}}.{{minor}}-${{ matrix.build }} - @@ -93,17 +93,6 @@ jobs: --amend joseluisq/php-fpm:$SEMVER_MINOR-armv6 \ --amend joseluisq/php-fpm:$SEMVER_MINOR-armv7 docker manifest push joseluisq/php-fpm:$SEMVER_MINOR - - - name: Push latest (PHP 8.3 or newer) - run: | - docker manifest create \ - joseluisq/php-fpm:latest \ - --amend joseluisq/php-fpm:$SEMVER_MINOR-amd64 \ - --amend joseluisq/php-fpm:$SEMVER_MINOR-386 \ - --amend joseluisq/php-fpm:$SEMVER_MINOR-arm64 \ - --amend joseluisq/php-fpm:$SEMVER_MINOR-armv6 \ - --amend joseluisq/php-fpm:$SEMVER_MINOR-armv7 - docker manifest push joseluisq/php-fpm:latest - name: Pull all images run: | @@ -123,14 +112,3 @@ jobs: --amend joseluisq/php-fpm:$SEMVER_MINOR-armv6 \ --amend joseluisq/php-fpm:$SEMVER_MINOR-armv7 docker manifest push joseluisq/php-fpm:$SEMVER - - - name: Push semver major alias (PHP 8.3 or newer) - run: | - docker manifest create \ - joseluisq/php-fpm:$SEMVER_MAJOR \ - --amend joseluisq/php-fpm:$SEMVER_MINOR-amd64 \ - --amend joseluisq/php-fpm:$SEMVER_MINOR-386 \ - --amend joseluisq/php-fpm:$SEMVER_MINOR-arm64 \ - --amend joseluisq/php-fpm:$SEMVER_MINOR-armv6 \ - --amend joseluisq/php-fpm:$SEMVER_MINOR-armv7 - docker manifest push joseluisq/php-fpm:$SEMVER_MAJOR diff --git a/.github/workflows/release-8.4.yml b/.github/workflows/release-8.4.yml new file mode 100644 index 0000000..44f9dc8 --- /dev/null +++ b/.github/workflows/release-8.4.yml @@ -0,0 +1,136 @@ +name: release-v8.4 +on: + push: + tags: + - 'v8.4.[0-9]+' + - 'v8.4.[0-9]+-beta.[0-9]+' + +jobs: + docker-build: + runs-on: ubuntu-22.04 + strategy: + matrix: + build: + - amd64 + - 386 + - arm64 + - armv7 + - armv6 + include: + - build: amd64 + arch: linux/amd64 + - build: 386 + arch: linux/386 + - build: arm64 + arch: linux/arm64 + - build: armv6 + arch: linux/arm/v6 + - build: armv7 + arch: linux/arm/v7 + name: PHP 8.4 (${{ matrix.build }}) + steps: + - + name: Checkout + uses: actions/checkout@v4 + - + name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - + name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: joseluisq/php-fpm + flavor: | + latest=true + tags: | + type=semver,pattern={{major}}.{{minor}}-${{ matrix.build }} + - + name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - + name: Login to DockerHub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - + name: Build and push + uses: docker/build-push-action@v5 + with: + push: true + provenance: false + context: . + platforms: ${{ matrix.arch }} + file: 8.4-fpm/Dockerfile + tags: ${{ steps.meta.outputs.tags }} + + docker-manifest: + needs: docker-build + runs-on: ubuntu-22.04 + steps: + - name: Set envs + run: | + github_ref=${GITHUB_REF#refs/tags/} + SEMVER=${github_ref##*v} + echo "SEMVER=${SEMVER}" >> $GITHUB_ENV + echo "SEMVER_MAJOR=${SEMVER%.*.*}" >> $GITHUB_ENV + echo "SEMVER_MINOR=${SEMVER%.*}" >> $GITHUB_ENV + - + name: Login to DockerHub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - + name: Push semver minor alias + run: | + docker manifest create \ + joseluisq/php-fpm:$SEMVER_MINOR \ + --amend joseluisq/php-fpm:$SEMVER_MINOR-amd64 \ + --amend joseluisq/php-fpm:$SEMVER_MINOR-386 \ + --amend joseluisq/php-fpm:$SEMVER_MINOR-arm64 \ + --amend joseluisq/php-fpm:$SEMVER_MINOR-armv6 \ + --amend joseluisq/php-fpm:$SEMVER_MINOR-armv7 + docker manifest push joseluisq/php-fpm:$SEMVER_MINOR + - + name: Push latest (PHP 8.4 or newer) + run: | + docker manifest create \ + joseluisq/php-fpm:latest \ + --amend joseluisq/php-fpm:$SEMVER_MINOR-amd64 \ + --amend joseluisq/php-fpm:$SEMVER_MINOR-386 \ + --amend joseluisq/php-fpm:$SEMVER_MINOR-arm64 \ + --amend joseluisq/php-fpm:$SEMVER_MINOR-armv6 \ + --amend joseluisq/php-fpm:$SEMVER_MINOR-armv7 + docker manifest push joseluisq/php-fpm:latest + - + name: Pull all images + run: | + docker pull joseluisq/php-fpm:$SEMVER_MINOR-amd64 + docker pull joseluisq/php-fpm:$SEMVER_MINOR-386 + docker pull joseluisq/php-fpm:$SEMVER_MINOR-arm64 + docker pull joseluisq/php-fpm:$SEMVER_MINOR-armv6 + docker pull joseluisq/php-fpm:$SEMVER_MINOR-armv7 + - + name: Push semver alias + run: | + docker manifest create \ + joseluisq/php-fpm:$SEMVER \ + --amend joseluisq/php-fpm:$SEMVER_MINOR-amd64 \ + --amend joseluisq/php-fpm:$SEMVER_MINOR-386 \ + --amend joseluisq/php-fpm:$SEMVER_MINOR-arm64 \ + --amend joseluisq/php-fpm:$SEMVER_MINOR-armv6 \ + --amend joseluisq/php-fpm:$SEMVER_MINOR-armv7 + docker manifest push joseluisq/php-fpm:$SEMVER + - + name: Push semver major alias (PHP 8.4 or newer) + run: | + docker manifest create \ + joseluisq/php-fpm:$SEMVER_MAJOR \ + --amend joseluisq/php-fpm:$SEMVER_MINOR-amd64 \ + --amend joseluisq/php-fpm:$SEMVER_MINOR-386 \ + --amend joseluisq/php-fpm:$SEMVER_MINOR-arm64 \ + --amend joseluisq/php-fpm:$SEMVER_MINOR-armv6 \ + --amend joseluisq/php-fpm:$SEMVER_MINOR-armv7 + docker manifest push joseluisq/php-fpm:$SEMVER_MAJOR From ab92f1661ac27955854840aac21367b294f3c49a Mon Sep 17 00:00:00 2001 From: Jose Quintana Date: Mon, 30 Dec 2024 18:47:07 +0100 Subject: [PATCH 3/3] v8.4.2 --- 8.4-fpm/Dockerfile | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/8.4-fpm/Dockerfile b/8.4-fpm/Dockerfile index dcd7d78..9bde427 100644 --- a/8.4-fpm/Dockerfile +++ b/8.4-fpm/Dockerfile @@ -1,4 +1,4 @@ -FROM php:8.4.1-fpm-alpine3.20 +FROM php:8.4.2-fpm-alpine3.20 LABEL Maintainer="Jose Quintana " \ Description="PHP-FPM v8.4 with essential extensions on top of Alpine Linux." @@ -16,6 +16,9 @@ ARG SWOOLE_VERSION="6.0.0" # # Imagick - https://github.com/Imagick/imagick # ARG IMAGICK_COMMIT="28f27044e435a2b203e32675e942eb8de620ee58" +# PSR - https://github.com/jbboehr/php-psr +ARG PSR_COMMIT="44cebb62d14846686de58022366a8eaf37e47c6a" + # Install dependencies RUN set -eux \ && apk add --no-cache \ @@ -26,8 +29,8 @@ RUN set -eux \ gettext \ gmp \ icu-libs \ - imagemagick \ - imap \ + # imagemagick \ + # imap \ libffi \ libgmpxx \ libintl \ @@ -71,8 +74,8 @@ RUN set -eux \ git \ gmp-dev \ icu-dev \ - imagemagick-dev \ - imap-dev \ + # imagemagick-dev \ + # imap-dev \ krb5-dev \ libc-dev \ libjpeg-turbo-dev \ @@ -152,11 +155,11 @@ RUN set -eux \ && docker-php-ext-install -j$(nproc) exif \ && true \ \ -# Install imap - && docker-php-ext-configure imap --with-kerberos --with-imap-ssl --with-imap \ - && docker-php-ext-install -j$(nproc) imap \ - && true \ -\ +# # Install imap +# && docker-php-ext-configure imap --with-kerberos --with-imap-ssl --with-imap \ +# && docker-php-ext-install -j$(nproc) imap \ +# && true \ +# \ # # Install imagick from source (temporarily) # && mkdir -p /opt/imagick \ # && cd /opt/imagick \ @@ -218,7 +221,7 @@ RUN set -eux \ && true \ \ # Install pdo_mysql - && docker-php-ext-configure pdo_mysql --with-zlib-dir=/usr \ + && docker-php-ext-configure pdo_mysql \ && docker-php-ext-install -j$(nproc) pdo_mysql \ && true \ \ @@ -258,7 +261,15 @@ RUN set -eux \ fi \ \ # Install psr - && pecl install psr \ + && mkdir -p /opt/psr \ + && cd /opt/psr \ + && git init \ + && git remote add origin https://github.com/jbboehr/php-psr.git \ + && git fetch origin ${PSR_COMMIT} \ + && git checkout ${PSR_COMMIT} \ + && phpize && ./configure \ + && make -j$(nproc) \ + && make -j$(nproc) install \ && docker-php-ext-enable psr \ && true \ \