From 236f8a776420f3a45d73cdc662b9733ecd31d0df Mon Sep 17 00:00:00 2001 From: le0m Date: Fri, 13 Dec 2024 15:51:41 +0100 Subject: [PATCH] feat: chialab/php-compat images --- .github/workflows/compat.yml | 93 ++++++++++ compat/Dockerfile.5.6 | 260 ++++++++++++++++++++++++++++ compat/Dockerfile.5.6-apache | 325 +++++++++++++++++++++++++++++++++++ compat/Dockerfile.5.6-fpm | 300 ++++++++++++++++++++++++++++++++ compat/Makefile | 85 +++++++++ compat/README.md | 82 +++++++++ dev/README.md | 2 +- pcov/README.md | 2 +- xhprof/README.md | 2 +- 9 files changed, 1148 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/compat.yml create mode 100644 compat/Dockerfile.5.6 create mode 100644 compat/Dockerfile.5.6-apache create mode 100644 compat/Dockerfile.5.6-fpm create mode 100644 compat/Makefile create mode 100644 compat/README.md diff --git a/.github/workflows/compat.yml b/.github/workflows/compat.yml new file mode 100644 index 0000000..e1a6379 --- /dev/null +++ b/.github/workflows/compat.yml @@ -0,0 +1,93 @@ +name: Build, test and publish compatibility images + +on: + schedule: + # chosen by fair dice roll + - cron: '42 18 * * 3' + push: + branches: + - main + pull_request: + types: [opened, synchronize] + +jobs: + test: + name: Build and test images + runs-on: ubuntu-latest + if: ${{ !contains(github.event.commits[0].message, '[skip ci]') && !contains(github.event.commits[0].message, '[ci skip]') }} + strategy: + matrix: + version: [ '5.6' ] + flavor: [ '', '-apache', '-fpm' ] + services: + registry: + image: registry:2 + ports: + - 5000:5000 + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Build image for testing + uses: docker/build-push-action@v5 + with: + cache-from: type=registry,ref=chialab/php-compat:${{ matrix.version }}${{ matrix.flavor }} + cache-to: type=inline + context: ./compat + file: ${{ format('compat/{0}.{1}{2}', 'Dockerfile', matrix.version, matrix.flavor) }} + tags: localhost:5000/chialab/php-compat:${{ matrix.version }}${{ matrix.flavor }} + push: true + + - name: Test image + env: + REGISTRY: localhost:5000/ + VERSION: ${{ matrix.version }}${{ matrix.flavor }} + run: 'docker pull localhost:5000/chialab/php-compat:${{ matrix.version }}${{ matrix.flavor }} && make -C compat test' + + publish: + name: Build and publish multi-architecture images + runs-on: ubuntu-latest + needs: test + if: ${{ github.event_name != 'pull_request' && !contains(github.event.commits[0].message, '[skip ci]') && !contains(github.event.commits[0].message, '[ci skip]') }} + strategy: + matrix: + version: [ '5.6' ] + flavor: [ '', '-apache', '-fpm' ] + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up QEMU + run: | + docker run --rm --privileged multiarch/qemu-user-static --reset -p yes + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + with: + driver-opts: network=host + + - name: Login to DockerHub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build image and push to registry + uses: docker/build-push-action@v5 + with: + platforms: linux/amd64,linux/arm64 + cache-from: type=registry,ref=chialab/php-compat:${{ matrix.version }}${{ matrix.flavor }} + cache-to: type=inline + context: ./compat + file: ${{ format('compat/{0}.{1}{2}', 'Dockerfile', matrix.version, matrix.flavor) }} + tags: | + chialab/php-compat:${{ matrix.version }}${{ matrix.flavor }} + ghcr.io/chialab/php-compat:${{ matrix.version }}${{ matrix.flavor }} + push: true diff --git a/compat/Dockerfile.5.6 b/compat/Dockerfile.5.6 new file mode 100644 index 0000000..c5f5d0d --- /dev/null +++ b/compat/Dockerfile.5.6 @@ -0,0 +1,260 @@ +# +# This is taken from the official PHP image's Dockerfile (https://github.com/docker-library/php/tree/783878384a8f3953ed571e5a34ba0fe546726c85) +# and slightly fixed to work in this day and age. +# + +FROM debian:stretch-slim + +LABEL maintainer="dev@chialab.io" + +# Fix Debian 9 (Stretch) source list, because it has been moved to archive, and update packages. +RUN sed -i -e 's/deb.debian.org/archive.debian.org/g' \ + -e 's/security.debian.org/archive.debian.org/g' \ + -e '/stretch-updates/d' /etc/apt/sources.list \ + && apt-get update && apt-get upgrade -y + +# prevent Debian's PHP packages from being installed +# https://github.com/docker-library/php/pull/542 +RUN set -eux; \ + { \ + echo 'Package: php*'; \ + echo 'Pin: release *'; \ + echo 'Pin-Priority: -1'; \ + } > /etc/apt/preferences.d/no-debian-php + +# dependencies required for running "phpize" +# (see persistent deps below) +ENV PHPIZE_DEPS \ + autoconf \ + dpkg-dev \ + file \ + g++ \ + gcc \ + libc-dev \ + make \ + pkg-config \ + re2c + +# persistent / runtime deps +RUN apt-get update && apt-get install -y \ + $PHPIZE_DEPS \ + ca-certificates \ + curl \ + xz-utils \ + --no-install-recommends && rm -r /var/lib/apt/lists/* + +ENV PHP_INI_DIR /usr/local/etc/php +RUN mkdir -p $PHP_INI_DIR/conf.d + +#### +#### + +# Apply stack smash protection to functions using local buffers and alloca() +# Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64) +# Enable optimization (-O2) +# Enable linker optimization (this sorts the hash buckets to improve cache locality, and is non-default) +# Adds GNU HASH segments to generated executables (this is used if present, and is much faster than sysv hash; in this configuration, sysv hash is also generated) +# https://github.com/docker-library/php/issues/272 +ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2" +ENV PHP_CPPFLAGS="$PHP_CFLAGS" +ENV PHP_LDFLAGS="-Wl,-O1 -Wl,--hash-style=both -pie" + +ENV GPG_KEYS 0BD78B5F97500D450838F95DFE857D9A90D90EC1 6E4F6AB321FDC07F2C332E3AC2BF0BC433CFC8B3 + +ENV PHP_VERSION 5.6.40 +ENV PHP_URL="https://secure.php.net/get/php-5.6.40.tar.xz/from/this/mirror" PHP_ASC_URL="https://secure.php.net/get/php-5.6.40.tar.xz.asc/from/this/mirror" +ENV PHP_SHA256="1369a51eee3995d7fbd1c5342e5cc917760e276d561595b6052b21ace2656d1c" PHP_MD5="" + +RUN set -xe; \ + \ + fetchDeps=' \ + wget \ + '; \ + if ! command -v gpg > /dev/null; then \ + fetchDeps="$fetchDeps \ + dirmngr \ + gnupg \ + "; \ + fi; \ + apt-get update; \ + apt-get install -y --no-install-recommends $fetchDeps; \ + rm -rf /var/lib/apt/lists/*; \ + \ + mkdir -p /usr/src; \ + cd /usr/src; \ + \ + wget -O php.tar.xz "$PHP_URL"; \ + \ + if [ -n "$PHP_SHA256" ]; then \ + echo "$PHP_SHA256 *php.tar.xz" | sha256sum -c -; \ + fi; \ + if [ -n "$PHP_MD5" ]; then \ + echo "$PHP_MD5 *php.tar.xz" | md5sum -c -; \ + fi; \ + \ + if [ -n "$PHP_ASC_URL" ]; then \ + wget -O php.tar.xz.asc "$PHP_ASC_URL"; \ + export GNUPGHOME="$(mktemp -d)"; \ + for key in $GPG_KEYS; do \ + gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \ + done; \ + gpg --batch --verify php.tar.xz.asc php.tar.xz; \ + command -v gpgconf > /dev/null && gpgconf --kill all; \ + rm -rf "$GNUPGHOME"; \ + fi; \ + \ + apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false $fetchDeps + +COPY --from=php:5.6 /usr/local/bin/docker-php-source /usr/local/bin/ + +RUN set -eux; \ + \ + savedAptMark="$(apt-mark showmanual)"; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + libcurl4-openssl-dev \ + libedit-dev \ + libsqlite3-dev \ + libssl1.0-dev \ + libxml2-dev \ + zlib1g-dev \ + libmariadb2 libmariadbclient-dev-compat \ + ${PHP_EXTRA_BUILD_DEPS:-} \ + ; \ + rm -rf /var/lib/apt/lists/*; \ + \ + export \ + CFLAGS="$PHP_CFLAGS" \ + CPPFLAGS="$PHP_CPPFLAGS" \ + LDFLAGS="$PHP_LDFLAGS" \ + ; \ + docker-php-source extract; \ + cd /usr/src/php; \ + gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \ + debMultiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)"; \ +# https://bugs.php.net/bug.php?id=74125 + if [ ! -d /usr/include/curl ]; then \ + ln -sT "/usr/include/$debMultiarch/curl" /usr/local/include/curl; \ + fi; \ + ./configure \ + --build="$gnuArch" \ + --with-config-file-path="$PHP_INI_DIR" \ + --with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \ + \ +# make sure invalid --configure-flags are fatal errors intead of just warnings + --enable-option-checking=fatal \ + \ +# https://github.com/docker-library/php/issues/439 + --with-mhash \ + \ +# --enable-ftp is included here because ftp_ssl_connect() needs ftp to be compiled statically (see https://github.com/docker-library/php/issues/236) + --enable-ftp \ +# --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195) + --enable-mbstring \ +# Use MariaDB's libmysqlclient library instead of mysqlnd to be able to communicate with MySQL 8+, which uses new locales of the utf8mb4 family that are unknown to old mysqlnd + --disable-mysqlnd \ + --with-mysql="/usr" \ + --with-mysqli="/usr/bin/mysql_config" \ + --with-pdo-mysql="/usr" \ + \ + --with-curl \ + --with-libedit \ + --with-openssl \ + --with-zlib \ + \ +# bundled pcre does not support JIT on s390x +# https://manpages.debian.org/stretch/libpcre3-dev/pcrejit.3.en.html#AVAILABILITY_OF_JIT_SUPPORT + $(test "$gnuArch" = 's390x-linux-gnu' && echo '--without-pcre-jit') \ + --with-libdir="lib/$debMultiarch" \ + \ + ${PHP_EXTRA_CONFIGURE_ARGS:-} \ + ; \ + make -j "$(nproc)"; \ + make install; \ + find /usr/local/bin /usr/local/sbin -type f -executable -exec strip --strip-all '{}' + || true; \ + make clean; \ + \ +# https://github.com/docker-library/php/issues/692 (copy default example "php.ini" files somewhere easily discoverable) + cp -v php.ini-* "$PHP_INI_DIR/"; \ + \ + cd /; \ + docker-php-source delete; \ + \ +# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies + apt-mark auto '.*' > /dev/null; \ + [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; \ + find /usr/local -type f -executable -exec ldd '{}' ';' \ + | awk '/=>/ { print $(NF-1) }' \ + | sort -u \ + | xargs -r dpkg-query --search \ + | cut -d: -f1 \ + | sort -u \ + | xargs -r apt-mark manual \ + ; \ + apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ + \ + php --version; \ + \ +# https://github.com/docker-library/php/issues/443 + pecl update-channels; \ + rm -rf /tmp/pear ~/.pearrc + +COPY --from=php:5.6 /usr/local/bin/docker-php-ext-* /usr/local/bin/docker-php-entrypoint /usr/local/bin/ + +ENTRYPOINT ["docker-php-entrypoint"] +#### +CMD ["php", "-a"] +#### + +# Download script to install PHP extensions and dependencies +ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/ + +RUN chmod +x /usr/local/bin/install-php-extensions + +RUN DEBIAN_FRONTEND=noninteractive apt-get update -q \ + && DEBIAN_FRONTEND=noninteractive apt-get install -qq -y \ + curl \ + git \ + zip unzip \ +# iconv, mbstring and pdo_sqlite are omitted as they are already installed + && PHP_EXTENSIONS=" \ + amqp \ + bcmath \ + bz2 \ + calendar \ + event \ + exif \ + gd \ + gettext \ + imagick \ + intl \ + ldap \ + mcrypt \ + memcached \ + mysql \ + mysqli \ + opcache \ + pdo_mysql \ + pdo_pgsql \ + pgsql \ + redis \ + soap \ + sockets \ + xsl \ + zip \ + " \ + && install-php-extensions $PHP_EXTENSIONS + +# Install Composer. +ENV PATH=$PATH:/root/composer/vendor/bin \ + COMPOSER_ALLOW_SUPERUSER=1 \ + COMPOSER_HOME=/root/composer +RUN cd /opt \ + # Download installer and check for its integrity. + && curl -sSL https://getcomposer.org/installer > composer-setup.php \ + && curl -sSL https://composer.github.io/installer.sha384sum > composer-setup.sha384sum \ + && sha384sum --check composer-setup.sha384sum \ + # Install Composer 2. + && php composer-setup.php --install-dir=/usr/local/bin --filename=composer --2 \ + # Remove installer files. + && rm /opt/composer-setup.php /opt/composer-setup.sha384sum diff --git a/compat/Dockerfile.5.6-apache b/compat/Dockerfile.5.6-apache new file mode 100644 index 0000000..ba8be70 --- /dev/null +++ b/compat/Dockerfile.5.6-apache @@ -0,0 +1,325 @@ +# +# This is taken from the official PHP image's Dockerfile (https://github.com/docker-library/php/tree/783878384a8f3953ed571e5a34ba0fe546726c85) +# and slightly fixed to work in this day and age. +# + +FROM debian:stretch-slim + +LABEL maintainer="dev@chialab.io" + +# Fix Debian 9 (Stretch) source list, because it has been moved to archive, and update packages. +RUN sed -i -e 's/deb.debian.org/archive.debian.org/g' \ + -e 's/security.debian.org/archive.debian.org/g' \ + -e '/stretch-updates/d' /etc/apt/sources.list \ + && apt-get update && apt-get upgrade -y + +# prevent Debian's PHP packages from being installed +# https://github.com/docker-library/php/pull/542 +RUN set -eux; \ + { \ + echo 'Package: php*'; \ + echo 'Pin: release *'; \ + echo 'Pin-Priority: -1'; \ + } > /etc/apt/preferences.d/no-debian-php + +# dependencies required for running "phpize" +# (see persistent deps below) +ENV PHPIZE_DEPS \ + autoconf \ + dpkg-dev \ + file \ + g++ \ + gcc \ + libc-dev \ + make \ + pkg-config \ + re2c + +# persistent / runtime deps +RUN apt-get update && apt-get install -y \ + $PHPIZE_DEPS \ + ca-certificates \ + curl \ + xz-utils \ + --no-install-recommends && rm -r /var/lib/apt/lists/* + +ENV PHP_INI_DIR /usr/local/etc/php +RUN mkdir -p $PHP_INI_DIR/conf.d + +#### +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + apache2 \ + && rm -rf /var/lib/apt/lists/* + +ENV APACHE_CONFDIR /etc/apache2 +ENV APACHE_ENVVARS $APACHE_CONFDIR/envvars + +RUN set -eux; \ + \ +# generically convert lines like +# export APACHE_RUN_USER=www-data +# into +# : ${APACHE_RUN_USER:=www-data} +# export APACHE_RUN_USER +# so that they can be overridden at runtime ("-e APACHE_RUN_USER=...") + sed -ri 's/^export ([^=]+)=(.*)$/: ${\1:=\2}\nexport \1/' "$APACHE_ENVVARS"; \ + \ +# setup directories and permissions + . "$APACHE_ENVVARS"; \ + for dir in \ + "$APACHE_LOCK_DIR" \ + "$APACHE_RUN_DIR" \ + "$APACHE_LOG_DIR" \ + /var/www/html \ + ; do \ + rm -rvf "$dir"; \ + mkdir -p "$dir"; \ + chown "$APACHE_RUN_USER:$APACHE_RUN_GROUP" "$dir"; \ +# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743) + chmod 777 "$dir"; \ + done; \ + \ +# logs should go to stdout / stderr + ln -sfT /dev/stderr "$APACHE_LOG_DIR/error.log"; \ + ln -sfT /dev/stdout "$APACHE_LOG_DIR/access.log"; \ + ln -sfT /dev/stdout "$APACHE_LOG_DIR/other_vhosts_access.log"; \ + chown -R --no-dereference "$APACHE_RUN_USER:$APACHE_RUN_GROUP" "$APACHE_LOG_DIR" + +# Apache + PHP requires preforking Apache for best results +RUN a2dismod mpm_event && a2enmod mpm_prefork + +# PHP files should be handled by PHP, and should be preferred over any other file type +RUN { \ + echo ''; \ + echo '\tSetHandler application/x-httpd-php'; \ + echo ''; \ + echo; \ + echo 'DirectoryIndex disabled'; \ + echo 'DirectoryIndex index.php index.html'; \ + echo; \ + echo ''; \ + echo '\tOptions -Indexes'; \ + echo '\tAllowOverride All'; \ + echo ''; \ + } | tee "$APACHE_CONFDIR/conf-available/docker-php.conf" \ + && a2enconf docker-php + +ENV PHP_EXTRA_BUILD_DEPS apache2-dev +ENV PHP_EXTRA_CONFIGURE_ARGS --with-apxs2 --disable-cgi +#### + +# Apply stack smash protection to functions using local buffers and alloca() +# Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64) +# Enable optimization (-O2) +# Enable linker optimization (this sorts the hash buckets to improve cache locality, and is non-default) +# Adds GNU HASH segments to generated executables (this is used if present, and is much faster than sysv hash; in this configuration, sysv hash is also generated) +# https://github.com/docker-library/php/issues/272 +ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2" +ENV PHP_CPPFLAGS="$PHP_CFLAGS" +ENV PHP_LDFLAGS="-Wl,-O1 -Wl,--hash-style=both -pie" + +ENV GPG_KEYS 0BD78B5F97500D450838F95DFE857D9A90D90EC1 6E4F6AB321FDC07F2C332E3AC2BF0BC433CFC8B3 + +ENV PHP_VERSION 5.6.40 +ENV PHP_URL="https://secure.php.net/get/php-5.6.40.tar.xz/from/this/mirror" PHP_ASC_URL="https://secure.php.net/get/php-5.6.40.tar.xz.asc/from/this/mirror" +ENV PHP_SHA256="1369a51eee3995d7fbd1c5342e5cc917760e276d561595b6052b21ace2656d1c" PHP_MD5="" + +RUN set -xe; \ + \ + fetchDeps=' \ + wget \ + '; \ + if ! command -v gpg > /dev/null; then \ + fetchDeps="$fetchDeps \ + dirmngr \ + gnupg \ + "; \ + fi; \ + apt-get update; \ + apt-get install -y --no-install-recommends $fetchDeps; \ + rm -rf /var/lib/apt/lists/*; \ + \ + mkdir -p /usr/src; \ + cd /usr/src; \ + \ + wget -O php.tar.xz "$PHP_URL"; \ + \ + if [ -n "$PHP_SHA256" ]; then \ + echo "$PHP_SHA256 *php.tar.xz" | sha256sum -c -; \ + fi; \ + if [ -n "$PHP_MD5" ]; then \ + echo "$PHP_MD5 *php.tar.xz" | md5sum -c -; \ + fi; \ + \ + if [ -n "$PHP_ASC_URL" ]; then \ + wget -O php.tar.xz.asc "$PHP_ASC_URL"; \ + export GNUPGHOME="$(mktemp -d)"; \ + for key in $GPG_KEYS; do \ + gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \ + done; \ + gpg --batch --verify php.tar.xz.asc php.tar.xz; \ + command -v gpgconf > /dev/null && gpgconf --kill all; \ + rm -rf "$GNUPGHOME"; \ + fi; \ + \ + apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false $fetchDeps + +COPY --from=php:5.6-apache /usr/local/bin/docker-php-source /usr/local/bin/ + +RUN set -eux; \ + \ + savedAptMark="$(apt-mark showmanual)"; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + libcurl4-openssl-dev \ + libedit-dev \ + libsqlite3-dev \ + libssl1.0-dev \ + libxml2-dev \ + zlib1g-dev \ + libmariadb2 libmariadbclient-dev-compat \ + ${PHP_EXTRA_BUILD_DEPS:-} \ + ; \ + rm -rf /var/lib/apt/lists/*; \ + \ + export \ + CFLAGS="$PHP_CFLAGS" \ + CPPFLAGS="$PHP_CPPFLAGS" \ + LDFLAGS="$PHP_LDFLAGS" \ + ; \ + docker-php-source extract; \ + cd /usr/src/php; \ + gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \ + debMultiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)"; \ +# https://bugs.php.net/bug.php?id=74125 + if [ ! -d /usr/include/curl ]; then \ + ln -sT "/usr/include/$debMultiarch/curl" /usr/local/include/curl; \ + fi; \ + ./configure \ + --build="$gnuArch" \ + --with-config-file-path="$PHP_INI_DIR" \ + --with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \ + \ +# make sure invalid --configure-flags are fatal errors intead of just warnings + --enable-option-checking=fatal \ + \ +# https://github.com/docker-library/php/issues/439 + --with-mhash \ + \ +# --enable-ftp is included here because ftp_ssl_connect() needs ftp to be compiled statically (see https://github.com/docker-library/php/issues/236) + --enable-ftp \ +# --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195) + --enable-mbstring \ +# Use MariaDB's libmysqlclient library instead of mysqlnd to be able to communicate with MySQL 8+, which uses new locales of the utf8mb4 family that are unknown to old mysqlnd + --disable-mysqlnd \ + --with-mysql="/usr" \ + --with-mysqli="/usr/bin/mysql_config" \ + --with-pdo-mysql="/usr" \ + \ + --with-curl \ + --with-libedit \ + --with-openssl \ + --with-zlib \ + \ +# bundled pcre does not support JIT on s390x +# https://manpages.debian.org/stretch/libpcre3-dev/pcrejit.3.en.html#AVAILABILITY_OF_JIT_SUPPORT + $(test "$gnuArch" = 's390x-linux-gnu' && echo '--without-pcre-jit') \ + --with-libdir="lib/$debMultiarch" \ + \ + ${PHP_EXTRA_CONFIGURE_ARGS:-} \ + ; \ + make -j "$(nproc)"; \ + make install; \ + find /usr/local/bin /usr/local/sbin -type f -executable -exec strip --strip-all '{}' + || true; \ + make clean; \ + \ +# https://github.com/docker-library/php/issues/692 (copy default example "php.ini" files somewhere easily discoverable) + cp -v php.ini-* "$PHP_INI_DIR/"; \ + \ + cd /; \ + docker-php-source delete; \ + \ +# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies + apt-mark auto '.*' > /dev/null; \ + [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; \ + find /usr/local -type f -executable -exec ldd '{}' ';' \ + | awk '/=>/ { print $(NF-1) }' \ + | sort -u \ + | xargs -r dpkg-query --search \ + | cut -d: -f1 \ + | sort -u \ + | xargs -r apt-mark manual \ + ; \ + apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ + \ + php --version; \ + \ +# https://github.com/docker-library/php/issues/443 + pecl update-channels; \ + rm -rf /tmp/pear ~/.pearrc + +COPY --from=php:5.6-apache /usr/local/bin/docker-php-ext-* /usr/local/bin/docker-php-entrypoint /usr/local/bin/ + +ENTRYPOINT ["docker-php-entrypoint"] +#### +COPY --from=php:5.6-apache /usr/local/bin/apache2-foreground /usr/local/bin/ +WORKDIR /var/www/html + +EXPOSE 80 +CMD ["apache2-foreground"] +#### + +# Download script to install PHP extensions and dependencies +ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/ + +RUN chmod +x /usr/local/bin/install-php-extensions + +RUN DEBIAN_FRONTEND=noninteractive apt-get update -q \ + && DEBIAN_FRONTEND=noninteractive apt-get install -qq -y \ + curl \ + git \ + zip unzip \ +# iconv, mbstring and pdo_sqlite are omitted as they are already installed + && PHP_EXTENSIONS=" \ + amqp \ + bcmath \ + bz2 \ + calendar \ + event \ + exif \ + gd \ + gettext \ + imagick \ + intl \ + ldap \ + mcrypt \ + memcached \ + mysql \ + mysqli \ + opcache \ + pdo_mysql \ + pdo_pgsql \ + pgsql \ + redis \ + soap \ + sockets \ + xsl \ + zip \ + " \ + && install-php-extensions $PHP_EXTENSIONS \ + && if command -v a2enmod; then a2enmod rewrite; fi + +# Install Composer. +ENV PATH=$PATH:/root/composer/vendor/bin \ + COMPOSER_ALLOW_SUPERUSER=1 \ + COMPOSER_HOME=/root/composer +RUN cd /opt \ + # Download installer and check for its integrity. + && curl -sSL https://getcomposer.org/installer > composer-setup.php \ + && curl -sSL https://composer.github.io/installer.sha384sum > composer-setup.sha384sum \ + && sha384sum --check composer-setup.sha384sum \ + # Install Composer 2. + && php composer-setup.php --install-dir=/usr/local/bin --filename=composer --2 \ + # Remove installer files. + && rm /opt/composer-setup.php /opt/composer-setup.sha384sum diff --git a/compat/Dockerfile.5.6-fpm b/compat/Dockerfile.5.6-fpm new file mode 100644 index 0000000..ee8bd8f --- /dev/null +++ b/compat/Dockerfile.5.6-fpm @@ -0,0 +1,300 @@ +# +# This is taken from the official PHP image's Dockerfile (https://github.com/docker-library/php/tree/783878384a8f3953ed571e5a34ba0fe546726c85) +# and slightly fixed to work in this day and age. +# + +FROM debian:stretch-slim + +LABEL maintainer="dev@chialab.io" + +# Fix Debian 9 (Stretch) source list, because it has been moved to archive, and update packages. +RUN sed -i -e 's/deb.debian.org/archive.debian.org/g' \ + -e 's/security.debian.org/archive.debian.org/g' \ + -e '/stretch-updates/d' /etc/apt/sources.list \ + && apt-get update && apt-get upgrade -y + +# prevent Debian's PHP packages from being installed +# https://github.com/docker-library/php/pull/542 +RUN set -eux; \ + { \ + echo 'Package: php*'; \ + echo 'Pin: release *'; \ + echo 'Pin-Priority: -1'; \ + } > /etc/apt/preferences.d/no-debian-php + +# dependencies required for running "phpize" +# (see persistent deps below) +ENV PHPIZE_DEPS \ + autoconf \ + dpkg-dev \ + file \ + g++ \ + gcc \ + libc-dev \ + make \ + pkg-config \ + re2c + +# persistent / runtime deps +RUN apt-get update && apt-get install -y \ + $PHPIZE_DEPS \ + ca-certificates \ + curl \ + xz-utils \ + --no-install-recommends && rm -r /var/lib/apt/lists/* + +ENV PHP_INI_DIR /usr/local/etc/php +RUN mkdir -p $PHP_INI_DIR/conf.d + +#### +ENV PHP_EXTRA_CONFIGURE_ARGS --enable-fpm --with-fpm-user=www-data --with-fpm-group=www-data --disable-cgi +#### + +# Apply stack smash protection to functions using local buffers and alloca() +# Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64) +# Enable optimization (-O2) +# Enable linker optimization (this sorts the hash buckets to improve cache locality, and is non-default) +# Adds GNU HASH segments to generated executables (this is used if present, and is much faster than sysv hash; in this configuration, sysv hash is also generated) +# https://github.com/docker-library/php/issues/272 +ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2" +ENV PHP_CPPFLAGS="$PHP_CFLAGS" +ENV PHP_LDFLAGS="-Wl,-O1 -Wl,--hash-style=both -pie" + +ENV GPG_KEYS 0BD78B5F97500D450838F95DFE857D9A90D90EC1 6E4F6AB321FDC07F2C332E3AC2BF0BC433CFC8B3 + +ENV PHP_VERSION 5.6.40 +ENV PHP_URL="https://secure.php.net/get/php-5.6.40.tar.xz/from/this/mirror" PHP_ASC_URL="https://secure.php.net/get/php-5.6.40.tar.xz.asc/from/this/mirror" +ENV PHP_SHA256="1369a51eee3995d7fbd1c5342e5cc917760e276d561595b6052b21ace2656d1c" PHP_MD5="" + +RUN set -xe; \ + \ + fetchDeps=' \ + wget \ + '; \ + if ! command -v gpg > /dev/null; then \ + fetchDeps="$fetchDeps \ + dirmngr \ + gnupg \ + "; \ + fi; \ + apt-get update; \ + apt-get install -y --no-install-recommends $fetchDeps; \ + rm -rf /var/lib/apt/lists/*; \ + \ + mkdir -p /usr/src; \ + cd /usr/src; \ + \ + wget -O php.tar.xz "$PHP_URL"; \ + \ + if [ -n "$PHP_SHA256" ]; then \ + echo "$PHP_SHA256 *php.tar.xz" | sha256sum -c -; \ + fi; \ + if [ -n "$PHP_MD5" ]; then \ + echo "$PHP_MD5 *php.tar.xz" | md5sum -c -; \ + fi; \ + \ + if [ -n "$PHP_ASC_URL" ]; then \ + wget -O php.tar.xz.asc "$PHP_ASC_URL"; \ + export GNUPGHOME="$(mktemp -d)"; \ + for key in $GPG_KEYS; do \ + gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \ + done; \ + gpg --batch --verify php.tar.xz.asc php.tar.xz; \ + command -v gpgconf > /dev/null && gpgconf --kill all; \ + rm -rf "$GNUPGHOME"; \ + fi; \ + \ + apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false $fetchDeps + +COPY --from=php:5.6-fpm /usr/local/bin/docker-php-source /usr/local/bin/ + +RUN set -eux; \ + \ + savedAptMark="$(apt-mark showmanual)"; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + libcurl4-openssl-dev \ + libedit-dev \ + libsqlite3-dev \ + libssl1.0-dev \ + libxml2-dev \ + zlib1g-dev \ + libmariadb2 libmariadbclient-dev-compat \ + ${PHP_EXTRA_BUILD_DEPS:-} \ + ; \ + rm -rf /var/lib/apt/lists/*; \ + \ + export \ + CFLAGS="$PHP_CFLAGS" \ + CPPFLAGS="$PHP_CPPFLAGS" \ + LDFLAGS="$PHP_LDFLAGS" \ + ; \ + docker-php-source extract; \ + cd /usr/src/php; \ + gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \ + debMultiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)"; \ +# https://bugs.php.net/bug.php?id=74125 + if [ ! -d /usr/include/curl ]; then \ + ln -sT "/usr/include/$debMultiarch/curl" /usr/local/include/curl; \ + fi; \ + ./configure \ + --build="$gnuArch" \ + --with-config-file-path="$PHP_INI_DIR" \ + --with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \ + \ +# make sure invalid --configure-flags are fatal errors intead of just warnings + --enable-option-checking=fatal \ + \ +# https://github.com/docker-library/php/issues/439 + --with-mhash \ + \ +# --enable-ftp is included here because ftp_ssl_connect() needs ftp to be compiled statically (see https://github.com/docker-library/php/issues/236) + --enable-ftp \ +# --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195) + --enable-mbstring \ +# Use MariaDB's libmysqlclient library instead of mysqlnd to be able to communicate with MySQL 8+, which uses new locales of the utf8mb4 family that are unknown to old mysqlnd + --disable-mysqlnd \ + --with-mysql="/usr" \ + --with-mysqli="/usr/bin/mysql_config" \ + --with-pdo-mysql="/usr" \ + \ + --with-curl \ + --with-libedit \ + --with-openssl \ + --with-zlib \ + \ +# bundled pcre does not support JIT on s390x +# https://manpages.debian.org/stretch/libpcre3-dev/pcrejit.3.en.html#AVAILABILITY_OF_JIT_SUPPORT + $(test "$gnuArch" = 's390x-linux-gnu' && echo '--without-pcre-jit') \ + --with-libdir="lib/$debMultiarch" \ + \ + ${PHP_EXTRA_CONFIGURE_ARGS:-} \ + ; \ + make -j "$(nproc)"; \ + make install; \ + find /usr/local/bin /usr/local/sbin -type f -executable -exec strip --strip-all '{}' + || true; \ + make clean; \ + \ +# https://github.com/docker-library/php/issues/692 (copy default example "php.ini" files somewhere easily discoverable) + cp -v php.ini-* "$PHP_INI_DIR/"; \ + \ + cd /; \ + docker-php-source delete; \ + \ +# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies + apt-mark auto '.*' > /dev/null; \ + [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; \ + find /usr/local -type f -executable -exec ldd '{}' ';' \ + | awk '/=>/ { print $(NF-1) }' \ + | sort -u \ + | xargs -r dpkg-query --search \ + | cut -d: -f1 \ + | sort -u \ + | xargs -r apt-mark manual \ + ; \ + apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ + \ + php --version; \ + \ +# https://github.com/docker-library/php/issues/443 + pecl update-channels; \ + rm -rf /tmp/pear ~/.pearrc + +COPY --from=php:5.6-fpm /usr/local/bin/docker-php-ext-* /usr/local/bin/docker-php-entrypoint /usr/local/bin/ + +ENTRYPOINT ["docker-php-entrypoint"] +#### +WORKDIR /var/www/html + +RUN set -ex \ + && cd /usr/local/etc \ + && if [ -d php-fpm.d ]; then \ + # for some reason, upstream's php-fpm.conf.default has "include=NONE/etc/php-fpm.d/*.conf" + sed 's!=NONE/!=!g' php-fpm.conf.default | tee php-fpm.conf > /dev/null; \ + cp php-fpm.d/www.conf.default php-fpm.d/www.conf; \ + else \ + # PHP 5.x doesn't use "include=" by default, so we'll create our own simple config that mimics PHP 7+ for consistency + mkdir php-fpm.d; \ + cp php-fpm.conf.default php-fpm.d/www.conf; \ + { \ + echo '[global]'; \ + echo 'include=etc/php-fpm.d/*.conf'; \ + } | tee php-fpm.conf; \ + fi \ + && { \ + echo '[global]'; \ + echo 'error_log = /proc/self/fd/2'; \ + echo; \ + echo '[www]'; \ + echo '; if we send this to /proc/self/fd/1, it never appears'; \ + echo 'access.log = /proc/self/fd/2'; \ + echo; \ + echo 'clear_env = no'; \ + echo; \ + echo '; Ensure worker stdout and stderr are sent to the main error log.'; \ + echo 'catch_workers_output = yes'; \ + } | tee php-fpm.d/docker.conf \ + && { \ + echo '[global]'; \ + echo 'daemonize = no'; \ + echo; \ + echo '[www]'; \ + echo 'listen = 9000'; \ + } | tee php-fpm.d/zz-docker.conf + +EXPOSE 9000 +CMD ["php-fpm"] +#### + +# Download script to install PHP extensions and dependencies +ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/ + +RUN chmod +x /usr/local/bin/install-php-extensions + +RUN DEBIAN_FRONTEND=noninteractive apt-get update -q \ + && DEBIAN_FRONTEND=noninteractive apt-get install -qq -y \ + curl \ + git \ + zip unzip \ +# iconv, mbstring and pdo_sqlite are omitted as they are already installed + && PHP_EXTENSIONS=" \ + amqp \ + bcmath \ + bz2 \ + calendar \ + event \ + exif \ + gd \ + gettext \ + imagick \ + intl \ + ldap \ + mcrypt \ + memcached \ + mysql \ + mysqli \ + opcache \ + pdo_mysql \ + pdo_pgsql \ + pgsql \ + redis \ + soap \ + sockets \ + xsl \ + zip \ + " \ + && install-php-extensions $PHP_EXTENSIONS + +# Install Composer. +ENV PATH=$PATH:/root/composer/vendor/bin \ + COMPOSER_ALLOW_SUPERUSER=1 \ + COMPOSER_HOME=/root/composer +RUN cd /opt \ + # Download installer and check for its integrity. + && curl -sSL https://getcomposer.org/installer > composer-setup.php \ + && curl -sSL https://composer.github.io/installer.sha384sum > composer-setup.sha384sum \ + && sha384sum --check composer-setup.sha384sum \ + # Install Composer 2. + && php composer-setup.php --install-dir=/usr/local/bin --filename=composer --2 \ + # Remove installer files. + && rm /opt/composer-setup.php /opt/composer-setup.sha384sum diff --git a/compat/Makefile b/compat/Makefile new file mode 100644 index 0000000..3c3b7aa --- /dev/null +++ b/compat/Makefile @@ -0,0 +1,85 @@ +SHELL := /bin/bash +ALL: build +.PHONY: build test push + +IMAGE := chialab/php-compat +VERSION ?= latest +PHP_VERSION = $(firstword $(subst -, ,$(VERSION))) + +# Extensions. +EXTENSIONS := \ + amqp \ + bcmath \ + bz2 \ + calendar \ + event \ + exif \ + gd \ + gettext \ + iconv \ + imagick \ + intl \ + ldap \ + mbstring \ + memcached \ + mysqli \ + OPcache \ + pdo_mysql \ + pdo_pgsql \ + pgsql \ + redis \ + soap \ + xsl \ + zip \ + sockets +ifeq (,$(findstring $(PHP_VERSION), 7.2 7.3 7.4 8.0 8.1 8.2 8.3 8.4 latest alpine)) + # Add more extensions to PHP < 7.2. + EXTENSIONS += mcrypt +endif +ifeq (,$(findstring $(PHP_VERSION), 7.0 7.1 7.2 7.3 7.4 8.0 8.1 8.2 8.3 8.4 latest alpine)) + # Add more extensions to 5.x series images. + EXTENSIONS += mysql +endif + +build: + @echo " =====> Building $(REGISTRY)$(IMAGE):$(VERSION)..." + docker image build --quiet -t $(REGISTRY)$(IMAGE):$(VERSION) . + +test: + @echo -e "=====> Testing loaded extensions... \c" + @if [[ -z `docker image ls $(REGISTRY)$(IMAGE) | grep "\s$(VERSION)\s"` ]]; then \ + echo 'FAIL [Missing image!!!]'; \ + exit 1; \ + fi + @IMAGE_PHP_VERSION=`docker container run --rm $(REGISTRY)$(IMAGE):$(VERSION) sh -c '/bin/echo $$PHP_VERSION' | cut -d '.' -f 1,2`; \ + if [[ "$(PHP_VERSION)" != "latest" && "$${IMAGE_PHP_VERSION}" != "$(PHP_VERSION)" ]]; then \ + echo "FAIL [wrong PHP version: expected $(PHP_VERSION), got $${IMAGE_PHP_VERSION}]"; \ + exit 1; \ + fi + @modules=`docker container run --rm $(REGISTRY)$(IMAGE):$(VERSION) php -m`; \ + for ext in $(EXTENSIONS); do \ + if [[ "$${modules}" != *"$${ext}"* ]]; then \ + echo "FAIL [$${ext}]"; \ + exit 1; \ + fi \ + done + @if [[ "$(VERSION)" == *'-apache' ]]; then \ + apache=`docker container run --rm $(REGISTRY)$(IMAGE):$(VERSION) apache2ctl -M 2> /dev/null`; \ + if [[ "$${apache}" != *'rewrite_module'* ]]; then \ + echo 'FAIL [mod_rewrite]'; \ + exit 1; \ + fi \ + fi + @if [[ -z `docker container run --rm $(REGISTRY)$(IMAGE):$(VERSION) composer --version 2> /dev/null | grep '^Composer version 2\.[0-9][0-9]*'` ]]; then \ + echo 'FAIL [Composer]'; \ + exit 1; \ + fi + @mariadbClientApi=`docker container run --rm $(REGISTRY)$(IMAGE):$(VERSION) php -i | grep -e "Client API.*MariaDB" | wc -l`; \ + if [[ "$${mariadbClientApi}" -lt 4 ]]; then \ + echo 'FAIL [MariaDB]'; \ + exit 1; \ + fi + @echo 'OK' + +push: + docker image push $(REGISTRY)$(IMAGE):$(VERSION) diff --git a/compat/README.md b/compat/README.md new file mode 100644 index 0000000..a3ee651 --- /dev/null +++ b/compat/README.md @@ -0,0 +1,82 @@ +

+ + Docker PHP Images logo + +

+ +

+ Docker PHP images +

+ +

+ GitHub Workflow Status + Source link + Authors link + Docker Pulls + License +

+ +--- + +Compatibility docker images. + +### PHP 5.6 + +Built from the latest official PHP 5.6 Dockerfiles ([this](https://github.com/docker-library/php/tree/783878384a8f3953ed571e5a34ba0fe546726c85) commit), +with PHP compiled to use MariaDB's `libmysqlclient` connector. This fixes connections with MySQL 8.0+, which uses a default +collation not recognized by the official image's `mysqlnd` connector (`utf8mb4`). + +## Available tags +- `5.6` +- `5.6-apache` +- `5.6-fpm` + +## Installed extensions +The following modules and extensions have been enabled, +in addition to those you can already find in the [official PHP image](https://hub.docker.com/r/_/php/): + +- `amqp` +- `bcmath` +- `bz2` +- `calendar` +- `event` +- `exif` +- `gd` +- `gettext` +- `iconv` +- `imagick` +- `intl` +- `ldap` +- `mbstring` +- `mcrypt` (_only PHP ≤ 7.1_) +- `memcached` +- `mysql` (_only PHP 5.x_) +- `mysqli` +- `pcov` +- `pdo_mysql` +- `pdo_pgsql` +- `pgsql` +- `redis` +- `soap` +- `sockets` +- `xsl` +- `Zend OPcache` +- `zip` + +You will probably not need all this stuff. Even if having some extra extensions loaded ain't a big issue in most cases (especially in a development environment), you will very likely want to checkout this repository, remove unwanted extensions from the `Dockerfile`, and build your own image — for sometimes removing is easier than adding. 😉 + +## Composer +[Composer](https://getcomposer.org) is installed globally in all images. Please, refer to their documentation for usage hints. +Since 2020/11/01 both version 1 and 2 are installed, available through `composer1` and `composer2` commands respectively (`composer` in now a symlink to `composer2`). +[Prestissimo (composer plugin)](https://github.com/hirak/prestissimo) is installed globally in all images, for use with Composer version 1. It's a plugin that downloads packages in parallel to speed up the installation process of Composer packages. + +## Contributing +If you find an issue, or have a special wish not yet fulfilled, please [open an issue on GitHub](https://github.com/chialab/docker-php/issues) providing as many details as you can (the more you are specific about your problem, the easier it is for us to fix it). + +Pull requests are welcome, too! 😁 Please, run `make build` and `make test` before attempting a pull request. Also, it would be nice if you could stick to the [best practices for writing Dockerfiles](https://docs.docker.com/articles/dockerfile_best-practices/). + +--- + +## License + +Docker PHP Images is released under the [MIT](https://github.com/chialab/docker-php/blob/master/LICENSE) license. diff --git a/dev/README.md b/dev/README.md index 66fc1c1..4218d3f 100644 --- a/dev/README.md +++ b/dev/README.md @@ -9,7 +9,7 @@

- GitHub Workflow Status + GitHub Workflow Status Source link Authors link Docker Pulls diff --git a/pcov/README.md b/pcov/README.md index d8de3a2..b6e4700 100644 --- a/pcov/README.md +++ b/pcov/README.md @@ -9,7 +9,7 @@

- GitHub Workflow Status + GitHub Workflow Status Source link Authors link Docker Pulls diff --git a/xhprof/README.md b/xhprof/README.md index 2983023..cf26553 100644 --- a/xhprof/README.md +++ b/xhprof/README.md @@ -9,7 +9,7 @@

- GitHub Workflow Status + GitHub Workflow Status Source link Authors link Docker Pulls