diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 3ef8d590..90501aa3 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -25,7 +25,7 @@ jobs: script: | const matrix = { cpu: ['x86', 'arm'], - php_version: ['80', '81', '82', '83', '84'], + php_version: ['80', '81', '82', '83', '84', '85'], } // If this is a third-party pull request, skip ARM builds diff --git a/Makefile b/Makefile index e0e798d7..54d888cb 100644 --- a/Makefile +++ b/Makefile @@ -35,13 +35,13 @@ default: docker-images layers # Build Docker images *locally* -docker-images: docker-images-php-80 docker-images-php-81 docker-images-php-82 docker-images-php-83 docker-images-php-84 +docker-images: docker-images-php-80 docker-images-php-81 docker-images-php-82 docker-images-php-83 docker-images-php-84 docker-images-php-85 docker-images-php-%: PHP_VERSION=$* ${BAKE_COMMAND} --load # Build Lambda layers (zip files) *locally* -layers: layer-php-80 layer-php-81 layer-php-82 layer-php-83 layer-php-84 layer-php-80-fpm layer-php-81-fpm layer-php-82-fpm layer-php-83-fpm layer-php-84-fpm +layers: layer-php-80 layer-php-81 layer-php-82 layer-php-83 layer-php-84 layer-php-85 layer-php-80-fpm layer-php-81-fpm layer-php-82-fpm layer-php-83-fpm layer-php-84-fpm layer-php-85-fpm # Build the console layer only once (x86 and single PHP version) @if [ ${CPU} = "x86" ]; then \ $(MAKE) layer-console; \ @@ -57,7 +57,7 @@ layer-%: # Upload the layers to AWS Lambda # Uses the current AWS_PROFILE. Most users will not want to use this option # as this will publish all layers to all regions + publish all Docker images. -upload-layers: upload-layers-php-80 upload-layers-php-81 upload-layers-php-82 upload-layers-php-83 upload-layers-php-84 +upload-layers: upload-layers-php-80 upload-layers-php-81 upload-layers-php-82 upload-layers-php-83 upload-layers-php-84 upload-layers-php-85 # Upload the console layer only once (x86 and single PHP version) @if [ ${CPU} = "x86" ]; then \ LAYER_NAME=console $(MAKE) -C ./utils/lambda-publish publish-parallel; \ @@ -70,7 +70,7 @@ upload-layers-php-%: # Publish Docker images to Docker Hub. -upload-to-docker-hub: upload-to-docker-hub-php-80 upload-to-docker-hub-php-81 upload-to-docker-hub-php-82 upload-to-docker-hub-php-83 upload-to-docker-hub-php-84 +upload-to-docker-hub: upload-to-docker-hub-php-80 upload-to-docker-hub-php-81 upload-to-docker-hub-php-82 upload-to-docker-hub-php-83 upload-to-docker-hub-php-84 upload-to-docker-hub-php-85 upload-to-docker-hub-php-%: # Make sure we have defined the docker tag (test $(DOCKER_TAG)) && echo "Tagging images with \"${DOCKER_TAG}\"" || echo "You have to define environment variable DOCKER_TAG" @@ -89,12 +89,12 @@ upload-to-docker-hub-php-%: done -test: test-80 test-81 test-82 test-83 test-84 +test: test-80 test-81 test-82 test-83 test-84 test-85 test-%: cd tests && $(MAKE) test-$* -clean: clean-80 clean-81 clean-82 clean-83 clean-84 +clean: clean-80 clean-81 clean-82 clean-83 clean-84 clean-85 # Clear the build cache, else all images will be rebuilt using cached layers docker builder prune # Remove zip files diff --git a/layers/fpm-dev/Dockerfile b/layers/fpm-dev/Dockerfile index de1e8198..9a7176b0 100644 --- a/layers/fpm-dev/Dockerfile +++ b/layers/fpm-dev/Dockerfile @@ -10,14 +10,14 @@ ARG PHP_VERSION RUN mkdir -p /opt/bref/extensions # Install xdebug -RUN pecl install xdebug-3.4.5 -RUN cp $(php -r "echo ini_get('extension_dir');")/xdebug.so /opt/bref/extensions +RUN if [ $PHP_VERSION != "85" ]; then pecl install xdebug-3.4.5; fi +RUN if [ $PHP_VERSION != "85" ]; then cp $(php -r "echo ini_get('extension_dir');")/xdebug.so /opt/bref/extensions; fi # Install Blackfire # https://blackfire.io/docs/up-and-running/installation?action=install&mode=full&version=latest&mode=full&location=server&os=manual&language=php#install-the-php-probe ARG BLACKFIRE_VERSION=1.87.2 -RUN if [ $PHP_VERSION != "83" ] && [ $PHP_VERSION != "84" ] && [ $CPU_PREFIX == "" ]; then curl -A "Docker" -o /opt/bref/extensions/blackfire.so -L -s "https://packages.blackfire.io/binaries/blackfire-php/$BLACKFIRE_VERSION/blackfire-php-linux_amd64-php-"$PHP_VERSION".so"; fi -RUN if [ $PHP_VERSION != "83" ] && [ $PHP_VERSION != "84" ] && [ $CPU_PREFIX == "arm-" ]; then curl -A "Docker" -o /opt/bref/extensions/blackfire.so -L -s "https://packages.blackfire.io/binaries/blackfire-php/$BLACKFIRE_VERSION/blackfire-php-linux_arm64-php-"$PHP_VERSION".so"; fi +RUN if [ $PHP_VERSION != "83" ] && [ $PHP_VERSION != "84" ] && [ $PHP_VERSION != "85" ] && [ $CPU_PREFIX == "" ]; then curl -A "Docker" -o /opt/bref/extensions/blackfire.so -L -s "https://packages.blackfire.io/binaries/blackfire-php/$BLACKFIRE_VERSION/blackfire-php-linux_amd64-php-"$PHP_VERSION".so"; fi +RUN if [ $PHP_VERSION != "83" ] && [ $PHP_VERSION != "84" ] && [ $PHP_VERSION != "85" ] && [ $CPU_PREFIX == "arm-" ]; then curl -A "Docker" -o /opt/bref/extensions/blackfire.so -L -s "https://packages.blackfire.io/binaries/blackfire-php/$BLACKFIRE_VERSION/blackfire-php-linux_arm64-php-"$PHP_VERSION".so"; fi FROM bref/${CPU_PREFIX}php-${PHP_VERSION}-fpm diff --git a/layers/fpm/bref.ini b/layers/fpm/bref.ini index e7f260b9..808fdef4 100644 --- a/layers/fpm/bref.ini +++ b/layers/fpm/bref.ini @@ -47,4 +47,3 @@ upload_max_filesize=6M extension_dir=/opt/bref/extensions ; Extensions enabled by default extension=pdo_mysql.so -zend_extension=opcache.so diff --git a/layers/function/bref.ini b/layers/function/bref.ini index bd23234b..41527697 100644 --- a/layers/function/bref.ini +++ b/layers/function/bref.ini @@ -41,4 +41,3 @@ variables_order="EGPCS" extension_dir=/opt/bref/extensions ; Extensions enabled by default extension=pdo_mysql.so -zend_extension=opcache.so diff --git a/layers/opcache.ini b/layers/opcache.ini new file mode 100644 index 00000000..c30fa481 --- /dev/null +++ b/layers/opcache.ini @@ -0,0 +1 @@ +zend_extension=opcache.so diff --git a/php-80/Dockerfile b/php-80/Dockerfile index 5230fac4..df387ce4 100644 --- a/php-80/Dockerfile +++ b/php-80/Dockerfile @@ -514,6 +514,7 @@ COPY --link layers/bootstrap.php /opt/bref/bootstrap.php FROM isolation as function COPY --link layers/function/bref.ini /opt/bref/etc/php/conf.d/ +COPY --link layers/opcache.ini /opt/bref/etc/php/conf.d/ COPY --link layers/function/bootstrap.sh /opt/bootstrap # Copy files to /var/runtime to support deploying as a Docker image @@ -537,6 +538,7 @@ FROM isolation as fpm COPY --link --from=fpm-extension /bref-layer /opt COPY --link layers/fpm/bref.ini /opt/bref/etc/php/conf.d/ +COPY --link layers/opcache.ini /opt/bref/etc/php/conf.d/ COPY --link layers/fpm/bootstrap.sh /opt/bootstrap # Copy files to /var/runtime to support deploying as a Docker image diff --git a/php-81/Dockerfile b/php-81/Dockerfile index c6482d68..00bc0166 100644 --- a/php-81/Dockerfile +++ b/php-81/Dockerfile @@ -536,6 +536,7 @@ COPY --link layers/bootstrap.php /opt/bref/bootstrap.php FROM isolation as function COPY --link layers/function/bref.ini /opt/bref/etc/php/conf.d/ +COPY --link layers/opcache.ini /opt/bref/etc/php/conf.d/ COPY --link layers/function/bootstrap.sh /opt/bootstrap # Copy files to /var/runtime to support deploying as a Docker image @@ -559,6 +560,7 @@ FROM isolation as fpm COPY --link --from=fpm-extension /bref-layer /opt COPY --link layers/fpm/bref.ini /opt/bref/etc/php/conf.d/ +COPY --link layers/opcache.ini /opt/bref/etc/php/conf.d/ COPY --link layers/fpm/bootstrap.sh /opt/bootstrap # Copy files to /var/runtime to support deploying as a Docker image diff --git a/php-82/Dockerfile b/php-82/Dockerfile index 2b596784..8615907a 100644 --- a/php-82/Dockerfile +++ b/php-82/Dockerfile @@ -536,6 +536,7 @@ COPY --link layers/bootstrap.php /opt/bref/bootstrap.php FROM isolation as function COPY --link layers/function/bref.ini /opt/bref/etc/php/conf.d/ +COPY --link layers/opcache.ini /opt/bref/etc/php/conf.d/ COPY --link layers/function/bootstrap.sh /opt/bootstrap # Copy files to /var/runtime to support deploying as a Docker image @@ -559,6 +560,7 @@ FROM isolation as fpm COPY --link --from=fpm-extension /bref-layer /opt COPY --link layers/fpm/bref.ini /opt/bref/etc/php/conf.d/ +COPY --link layers/opcache.ini /opt/bref/etc/php/conf.d/ COPY --link layers/fpm/bootstrap.sh /opt/bootstrap # Copy files to /var/runtime to support deploying as a Docker image diff --git a/php-83/Dockerfile b/php-83/Dockerfile index 5d552622..574f0810 100644 --- a/php-83/Dockerfile +++ b/php-83/Dockerfile @@ -536,6 +536,7 @@ COPY --link layers/bootstrap.php /opt/bref/bootstrap.php FROM isolation as function COPY --link layers/function/bref.ini /opt/bref/etc/php/conf.d/ +COPY --link layers/opcache.ini /opt/bref/etc/php/conf.d/ COPY --link layers/function/bootstrap.sh /opt/bootstrap # Copy files to /var/runtime to support deploying as a Docker image @@ -559,6 +560,7 @@ FROM isolation as fpm COPY --link --from=fpm-extension /bref-layer /opt COPY --link layers/fpm/bref.ini /opt/bref/etc/php/conf.d/ +COPY --link layers/opcache.ini /opt/bref/etc/php/conf.d/ COPY --link layers/fpm/bootstrap.sh /opt/bootstrap # Copy files to /var/runtime to support deploying as a Docker image diff --git a/php-84/Dockerfile b/php-84/Dockerfile index a62eb86f..22393ffb 100644 --- a/php-84/Dockerfile +++ b/php-84/Dockerfile @@ -377,8 +377,8 @@ RUN make && make install ############################################################################### # SQLite # Since PHP 7.4, libsqlite must be installed (https://github.com/php/php-src/blob/99b8e67615159fc600a615e1e97f2d1cf18f14cb/UPGRADING#L616-L619) -# PHP 8.4 requires SQLite 3.13.0 or higher because the build uses the -# `SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION` constant. +# Since PHP 8.4, version 3.13.0 or higher of SQLite is required because the +# build uses the `SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION` constant. # See https://github.com/brefphp/aws-lambda-layers/pull/185 # Laravel 11 requires SQLite 3.35.0 or higher and Drupal 10 also requires a # newer version than the system version of 3.7.17. @@ -537,6 +537,7 @@ COPY --link layers/bootstrap.php /opt/bref/bootstrap.php FROM isolation as function COPY --link layers/function/bref.ini /opt/bref/etc/php/conf.d/ +COPY --link layers/opcache.ini /opt/bref/etc/php/conf.d/ COPY --link layers/function/bootstrap.sh /opt/bootstrap # Copy files to /var/runtime to support deploying as a Docker image @@ -560,6 +561,7 @@ FROM isolation as fpm COPY --link --from=fpm-extension /bref-layer /opt COPY --link layers/fpm/bref.ini /opt/bref/etc/php/conf.d/ +COPY --link layers/opcache.ini /opt/bref/etc/php/conf.d/ COPY --link layers/fpm/bootstrap.sh /opt/bootstrap # Copy files to /var/runtime to support deploying as a Docker image diff --git a/php-85/Dockerfile b/php-85/Dockerfile new file mode 100644 index 00000000..2b08da5d --- /dev/null +++ b/php-85/Dockerfile @@ -0,0 +1,603 @@ +# syntax = docker/dockerfile:1.4 + +# Can be "x86_64" or "arm64" +ARG IMAGE_VERSION_SUFFIX + +# https://www.php.net/downloads +ARG VERSION_PHP=8.5.0beta1 + + +# Lambda uses a custom AMI named Amazon Linux 2 +# https://docs.aws.amazon.com/lambda/latest/dg/current-supported-versions.html +# AWS provides a Docker image that we use here: +# https://github.com/amazonlinux/container-images/tree/amzn2 +FROM public.ecr.aws/lambda/provided:al2-${IMAGE_VERSION_SUFFIX} as build-environment + + +RUN set -xe \ + # Download yum repository data to cache + && yum makecache \ + # Install default development tools (gcc, make, etc) + && yum groupinstall -y "Development Tools" --setopt=group_package_types=mandatory,default + + +# The default version of cmake is 2.8.12. We need cmake to build a few of +# our libraries, and at least one library requires a version of cmake greater than that. +# Needed to build: +# - libzip: minimum required CMAKE version 3.0. +RUN LD_LIBRARY_PATH= yum install -y cmake3 +# Override the default `cmake` +RUN ln -s /usr/bin/cmake3 /usr/bin/cmake + + +# We need a base path for all the sourcecode we will build from. +ENV BUILD_DIR="/tmp/build" + +# Target installation path for all the binaries and libraries we will compile. +# We need to use /opt because that's where AWS Lambda layers are unzipped, +# and we need binaries (e.g. /opt/bin/php) to look for libraries in /opt/lib. +# Indeed, `/opt/lib` is a path Lambda looks for libraries by default (it is in `LD_LIBRARY_PATH`) +# AND the `/opt/lib` path will be hardcoded in the compiled binaries and libraries (called "rpath"). +# +# Note: the /opt directory will be completely recreated from scratch in the final images, +# so it's ok at this stage if we "pollute" it with plenty of extra libs/build artifacts. +ENV INSTALL_DIR="/opt" + +# We need some default compiler variables setup +ENV PKG_CONFIG_PATH="${INSTALL_DIR}/lib64/pkgconfig:${INSTALL_DIR}/lib/pkgconfig" \ + PKG_CONFIG="/usr/bin/pkg-config" \ + PATH="${INSTALL_DIR}/bin:${PATH}" + +ENV LD_LIBRARY_PATH="${INSTALL_DIR}/lib64:${INSTALL_DIR}/lib" + +# Enable parallelism by default for make and cmake (like make -j) +# See https://stackoverflow.com/a/50883540/245552 +ENV CMAKE_BUILD_PARALLEL_LEVEL=4 +ENV MAKEFLAGS='-j4' + +# Ensure we have all the directories we require in the container. +RUN mkdir -p ${BUILD_DIR} \ + ${INSTALL_DIR}/bin \ + ${INSTALL_DIR}/doc \ + ${INSTALL_DIR}/etc/php \ + ${INSTALL_DIR}/etc/php/conf.d \ + ${INSTALL_DIR}/include \ + ${INSTALL_DIR}/lib \ + ${INSTALL_DIR}/lib64 \ + ${INSTALL_DIR}/libexec \ + ${INSTALL_DIR}/sbin \ + ${INSTALL_DIR}/share + + +############################################################################### +# ZLIB Build +# We compile a newer version because Lambda uses an old version (1.2.7) that +# has a security vulnerability (CVE-2022-37434). +# See https://github.com/brefphp/aws-lambda-layers/pull/110 +# Can be removed once Lambda updates their version. +# https://github.com/madler/zlib/releases +ENV VERSION_ZLIB=1.3.1 +ENV ZLIB_BUILD_DIR=${BUILD_DIR}/zlib +RUN set -xe; \ + mkdir -p ${ZLIB_BUILD_DIR}; \ + curl -Ls https://github.com/madler/zlib/releases/download/v${VERSION_ZLIB}/zlib-${VERSION_ZLIB}.tar.gz \ + | tar xzC ${ZLIB_BUILD_DIR} --strip-components=1 +WORKDIR ${ZLIB_BUILD_DIR}/ +RUN set -xe; \ + make distclean \ + && CFLAGS="" \ + CPPFLAGS="-I${INSTALL_DIR}/include -I/usr/include" \ + LDFLAGS="-L${INSTALL_DIR}/lib64 -L${INSTALL_DIR}/lib" \ + ./configure \ + --prefix=${INSTALL_DIR} +RUN set -xe; \ + make install \ + && rm ${INSTALL_DIR}/lib/libz.a + + +############################################################################### +# OPENSSL +# https://github.com/openssl/openssl/releases +# Needs: +# - zlib +# Needed by: +# - curl +# - php +RUN yum install -y perl-IPC-Cmd +ENV VERSION_OPENSSL=3.5.2 +ENV OPENSSL_BUILD_DIR=${BUILD_DIR}/openssl +ENV CA_BUNDLE_SOURCE="https://curl.se/ca/cacert.pem" +ENV CA_BUNDLE="${INSTALL_DIR}/bref/ssl/cert.pem" +RUN set -xe; \ + mkdir -p ${OPENSSL_BUILD_DIR}; \ + curl -Ls https://github.com/openssl/openssl/releases/download/openssl-${VERSION_OPENSSL}/openssl-${VERSION_OPENSSL}.tar.gz \ + | tar xzC ${OPENSSL_BUILD_DIR} --strip-components=1 +WORKDIR ${OPENSSL_BUILD_DIR}/ +RUN CFLAGS="" \ + CPPFLAGS="-I${INSTALL_DIR}/include -I/usr/include" \ + LDFLAGS="-L${INSTALL_DIR}/lib64 -L${INSTALL_DIR}/lib" \ + ./config \ + --prefix=${INSTALL_DIR} \ + --openssldir=${INSTALL_DIR}/bref/ssl \ + --release \ + enable-tls1_3 \ + no-tests \ + shared \ + zlib +# Explicitly compile make without parallelism because it fails if we use -jX (no error message) +# I'm not 100% sure why, and I already lost 4 hours on this, but I found this: +# https://github.com/openssl/openssl/issues/9931 +# https://stackoverflow.com/questions/28639207/why-cant-i-compile-openssl-with-multiple-threads-make-j3 +# Run `make install_sw install_ssldirs` instead of `make install` to skip installing man pages https://github.com/openssl/openssl/issues/8170 +RUN make -j1 install_sw install_ssldirs +RUN mkdir -p ${INSTALL_DIR}/bref/ssl && curl -Lk -o ${CA_BUNDLE} ${CA_BUNDLE_SOURCE} + + +############################################################################### +# ICU +# We need to compile ICU from source because Amazon Linux 2 only has ICU 50.2 +# but PHP 8.5 requires ICU 57.1 or higher +# https://github.com/unicode-org/icu/releases +# Uses: +# - None +# Needed by: +# - libxml2 +# - php intl extension +ENV VERSION_ICU=77.1 +ENV ICU_BUILD_DIR=${BUILD_DIR}/icu +RUN set -xe; \ + mkdir -p ${ICU_BUILD_DIR}; \ + curl -Ls https://github.com/unicode-org/icu/releases/download/release-${VERSION_ICU//./-}/icu4c-${VERSION_ICU//./_}-src.tgz \ + | tar xzC ${ICU_BUILD_DIR} --strip-components=1 +WORKDIR ${ICU_BUILD_DIR}/source +RUN CFLAGS="" \ + CPPFLAGS="-I${INSTALL_DIR}/include -I/usr/include" \ + LDFLAGS="-L${INSTALL_DIR}/lib64 -L${INSTALL_DIR}/lib -Wl,-rpath,${INSTALL_DIR}/lib" \ + ./configure \ + --prefix=${INSTALL_DIR} \ + --enable-shared \ + --disable-static \ + --disable-samples \ + --disable-tests \ + --disable-extras \ + --disable-layoutex +RUN make && make install + + +############################################################################### +# LIBXML2 +# https://gitlab.gnome.org/GNOME/libxml2/-/releases +# Uses: +# - icu +# - zlib +# Needed by: +# - php +# - libnghttp2 +ENV VERSION_XML2=2.13.8 +ENV XML2_BUILD_DIR=${BUILD_DIR}/xml2 +RUN set -xe; \ + mkdir -p ${XML2_BUILD_DIR}; \ + curl -Ls https://download.gnome.org/sources/libxml2/${VERSION_XML2%.*}/libxml2-${VERSION_XML2}.tar.xz \ + | tar xJC ${XML2_BUILD_DIR} --strip-components=1 +WORKDIR ${XML2_BUILD_DIR}/ +RUN CFLAGS="" \ + CPPFLAGS="-I${INSTALL_DIR}/include -I/usr/include" \ + LDFLAGS="-L${INSTALL_DIR}/lib64 -L${INSTALL_DIR}/lib" \ + PATH="${INSTALL_DIR}/bin:${PATH}" \ + ICU_CFLAGS="-I${INSTALL_DIR}/include" \ + ICU_LIBS="-L${INSTALL_DIR}/lib -licui18n -licuuc -licudata" \ + ./configure \ + --prefix=${INSTALL_DIR} \ + --with-sysroot=${INSTALL_DIR} \ + --enable-shared \ + --disable-static \ + --with-html \ + --with-history \ + --enable-ipv6=no \ + --with-icu \ + --with-zlib \ + --without-python +RUN make install \ + && cp xml2-config ${INSTALL_DIR}/bin/xml2-config + + +############################################################################### +# LIBSSH2 +# https://github.com/libssh2/libssh2/releases +# Needs: +# - zlib +# - OpenSSL +# Needed by: +# - curl +ENV VERSION_LIBSSH2=1.11.1 +ENV LIBSSH2_BUILD_DIR=${BUILD_DIR}/libssh2 +RUN set -xe; \ + mkdir -p ${LIBSSH2_BUILD_DIR}/bin; \ + curl -Ls https://github.com/libssh2/libssh2/releases/download/libssh2-${VERSION_LIBSSH2}/libssh2-${VERSION_LIBSSH2}.tar.gz \ + | tar xzC ${LIBSSH2_BUILD_DIR} --strip-components=1 +WORKDIR ${LIBSSH2_BUILD_DIR}/bin/ +RUN CFLAGS="" \ + CPPFLAGS="-I${INSTALL_DIR}/include -I/usr/include" \ + LDFLAGS="-L${INSTALL_DIR}/lib64 -L${INSTALL_DIR}/lib" \ + cmake .. \ + # Build as a shared library (.so) instead of a static one + -DBUILD_SHARED_LIBS=ON \ + # Build with OpenSSL support + -DCRYPTO_BACKEND=OpenSSL \ + # Build with zlib support + -DENABLE_ZLIB_COMPRESSION=ON \ + -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} \ + -DCMAKE_BUILD_TYPE=RELEASE +RUN cmake --build . --target install + + +############################################################################### +# LIBNGHTTP2 +# This adds support for HTTP 2 requests in curl. +# See https://github.com/brefphp/bref/issues/727 and https://github.com/brefphp/bref/pull/740 +# https://github.com/nghttp2/nghttp2/releases +# Needs: +# - zlib +# - OpenSSL +# - libxml2 +# Needed by: +# - curl +ENV VERSION_NGHTTP2=1.66.0 +ENV NGHTTP2_BUILD_DIR=${BUILD_DIR}/nghttp2 +RUN set -xe; \ + mkdir -p ${NGHTTP2_BUILD_DIR}; \ + curl -Ls https://github.com/nghttp2/nghttp2/releases/download/v${VERSION_NGHTTP2}/nghttp2-${VERSION_NGHTTP2}.tar.gz \ + | tar xzC ${NGHTTP2_BUILD_DIR} --strip-components=1 +WORKDIR ${NGHTTP2_BUILD_DIR}/ +RUN CFLAGS="" \ + CPPFLAGS="-I${INSTALL_DIR}/include -I/usr/include" \ + LDFLAGS="-L${INSTALL_DIR}/lib64 -L${INSTALL_DIR}/lib" \ + ./configure \ + --enable-lib-only \ + --prefix=${INSTALL_DIR} +RUN make install + + +############################################################################### +# LIBPSL +# This adds support for the public suffix list in curl. +# https://github.com/rockdaboot/libpsl/releases +# Needed by: +# - curl +ENV VERSION_LIBPSL=0.21.5 +ENV LIBPSL_BUILD_DIR=${BUILD_DIR}/libpsl +RUN set -xe; \ + mkdir -p ${LIBPSL_BUILD_DIR}; \ + curl -Ls https://github.com/rockdaboot/libpsl/releases/download/${VERSION_LIBPSL}/libpsl-${VERSION_LIBPSL}.tar.gz \ + | tar xzC ${LIBPSL_BUILD_DIR} --strip-components=1 +WORKDIR ${LIBPSL_BUILD_DIR}/ +RUN CFLAGS="" \ + CPPFLAGS="-I${INSTALL_DIR}/include -I/usr/include" \ + LDFLAGS="-L${INSTALL_DIR}/lib64 -L${INSTALL_DIR}/lib" \ + ./configure \ + --prefix=${INSTALL_DIR} +RUN make -j $(nproc) && make install + + +############################################################################### +# CURL +# # https://github.com/curl/curl/releases +# # Needs: +# # - zlib +# # - OpenSSL +# # - libssh2 +# # - libnghttp2 +# # Needed by: +# # - php +ENV VERSION_CURL=8.14.1 +ENV CURL_BUILD_DIR=${BUILD_DIR}/curl +RUN set -xe; \ + mkdir -p ${CURL_BUILD_DIR}/bin; \ + curl -Ls https://github.com/curl/curl/archive/curl-${VERSION_CURL//./_}.tar.gz \ + | tar xzC ${CURL_BUILD_DIR} --strip-components=1 +WORKDIR ${CURL_BUILD_DIR}/ +RUN ./buildconf \ + && CFLAGS="" \ + CPPFLAGS="-I${INSTALL_DIR}/include -I/usr/include" \ + LDFLAGS="-L${INSTALL_DIR}/lib64 -L${INSTALL_DIR}/lib" \ + ./configure \ + --prefix=${INSTALL_DIR} \ + --with-ca-bundle=${CA_BUNDLE} \ + --enable-shared \ + --disable-static \ + --enable-optimize \ + --disable-warnings \ + --disable-dependency-tracking \ + --with-zlib \ + --enable-http \ + --enable-ftp \ + --enable-file \ + --enable-proxy \ + --enable-tftp \ + --enable-ipv6 \ + --enable-openssl-auto-load-config \ + --enable-cookies \ + --with-gnu-ld \ + --with-ssl \ + --with-libssh2 \ + --with-nghttp2 +RUN make install + + +############################################################################### +# LIBZIP +# https://github.com/nih-at/libzip/releases +# Needed by: +# - php +ENV VERSION_ZIP=1.11.4 +ENV ZIP_BUILD_DIR=${BUILD_DIR}/zip +RUN set -xe; \ + mkdir -p ${ZIP_BUILD_DIR}/bin/; \ + curl -Ls https://github.com/nih-at/libzip/releases/download/v${VERSION_ZIP}/libzip-${VERSION_ZIP}.tar.gz \ + | tar xzC ${ZIP_BUILD_DIR} --strip-components=1 +WORKDIR ${ZIP_BUILD_DIR}/bin/ +RUN CFLAGS="" \ + CPPFLAGS="-I${INSTALL_DIR}/include -I/usr/include" \ + LDFLAGS="-L${INSTALL_DIR}/lib64 -L${INSTALL_DIR}/lib" \ + cmake .. \ + -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} \ + -DCMAKE_BUILD_TYPE=RELEASE +RUN cmake --build . --target install + + +############################################################################### +# LIBSODIUM +# https://github.com/jedisct1/libsodium/releases +# Needed by: +# - php +ENV VERSION_LIBSODIUM=1.0.20 +ENV LIBSODIUM_BUILD_DIR=${BUILD_DIR}/libsodium +RUN set -xe; \ + mkdir -p ${LIBSODIUM_BUILD_DIR}; \ + curl -Ls https://github.com/jedisct1/libsodium/archive/${VERSION_LIBSODIUM}-RELEASE.tar.gz \ + | tar xzC ${LIBSODIUM_BUILD_DIR} --strip-components=1 +WORKDIR ${LIBSODIUM_BUILD_DIR}/ +RUN CFLAGS="" \ + CPPFLAGS="-I${INSTALL_DIR}/include -I/usr/include" \ + LDFLAGS="-L${INSTALL_DIR}/lib64 -L${INSTALL_DIR}/lib" \ + ./autogen.sh \ +&& ./configure --prefix=${INSTALL_DIR} +RUN make install + + +############################################################################### +# Postgres +# https://github.com/postgres/postgres/tags +# Needs: +# - OpenSSL +# Needed by: +# - php +ENV VERSION_POSTGRES=17.5 +ENV POSTGRES_BUILD_DIR=${BUILD_DIR}/postgres +RUN set -xe; \ + mkdir -p ${POSTGRES_BUILD_DIR}/bin; \ + curl -Ls https://github.com/postgres/postgres/archive/REL_${VERSION_POSTGRES//./_}.tar.gz \ + | tar xzC ${POSTGRES_BUILD_DIR} --strip-components=1 +WORKDIR ${POSTGRES_BUILD_DIR}/ +RUN CFLAGS="" \ + CPPFLAGS="-I${INSTALL_DIR}/include -I/usr/include" \ + LDFLAGS="-L${INSTALL_DIR}/lib64 -L${INSTALL_DIR}/lib" \ + ./configure --prefix=${INSTALL_DIR} --with-openssl --without-icu --without-readline +RUN cd ${POSTGRES_BUILD_DIR}/src/interfaces/libpq && make && make install +RUN cd ${POSTGRES_BUILD_DIR}/src/bin/pg_config && make && make install +RUN cd ${POSTGRES_BUILD_DIR}/src/backend && make generated-headers +RUN cd ${POSTGRES_BUILD_DIR}/src/include && make install + + +############################################################################### +# Oniguruma +# This library is not packaged in PHP since PHP 7.4. +# See https://github.com/php/php-src/blob/43dc7da8e3719d3e89bd8ec15ebb13f997bbbaa9/UPGRADING#L578-L581 +# We do not install the system version because I didn't manage to make it work... +# Ideally we shouldn't compile it ourselves. +# https://github.com/kkos/oniguruma/releases +# Needed by: +# - php mbstring +ENV VERSION_ONIG=6.9.10 +ENV ONIG_BUILD_DIR=${BUILD_DIR}/oniguruma +RUN set -xe; \ + mkdir -p ${ONIG_BUILD_DIR}; \ + curl -Ls https://github.com/kkos/oniguruma/releases/download/v${VERSION_ONIG}/onig-${VERSION_ONIG}.tar.gz \ + | tar xzC ${ONIG_BUILD_DIR} --strip-components=1 +WORKDIR ${ONIG_BUILD_DIR} +RUN ./configure --prefix=${INSTALL_DIR} +RUN make && make install + + +############################################################################### +# SQLite +# Since PHP 7.4, libsqlite must be installed (https://github.com/php/php-src/blob/99b8e67615159fc600a615e1e97f2d1cf18f14cb/UPGRADING#L616-L619) +# Since PHP 8.4, version 3.13.0 or higher of SQLite is required because the +# build uses the `SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION` constant. +# See https://github.com/brefphp/aws-lambda-layers/pull/185 +# Laravel 11 requires SQLite 3.35.0 or higher and Drupal 10 also requires a +# newer version than the system version of 3.7.17. +# https://laravel.com/docs/11.x/upgrade#sqlite-minimum-version +# https://www.sqlite.org/changes.html +# Needed by: +# - php +RUN LD_LIBRARY_PATH= yum install -y tcl +ENV VERSION_SQLITE=3.50.4 +ENV SQLITE_BUILD_DIR=${BUILD_DIR}/sqlite +RUN set -xe; \ + mkdir -p ${SQLITE_BUILD_DIR}; \ + curl -Ls https://github.com/sqlite/sqlite/archive/refs/tags/version-${VERSION_SQLITE}.tar.gz \ + | tar xzC ${SQLITE_BUILD_DIR} --strip-components=1 +WORKDIR ${SQLITE_BUILD_DIR} +RUN ./configure --prefix=${INSTALL_DIR} +RUN make && make install + + +############################################################################### +# Install some dev files for using old libraries already on the system +# readline-devel : needed for the readline extension +# gettext-devel : needed for the --with-gettext flag +# libxslt-devel : needed for the XSL extension +# libffi-devel : needed for the FFI extension +RUN LD_LIBRARY_PATH= yum install -y readline-devel gettext-devel libxslt-devel libffi-devel + + +# Note: this variable is used when building extra/custom extensions, do not remove +ENV PHP_BUILD_DIR=/tmp/php + +# PHP Build +# https://github.com/php/php-src/releases +# Needs: +# - zlib +# - libxml2 +# - openssl +# - readline +# - sodium +RUN mkdir -p ${PHP_BUILD_DIR} +WORKDIR ${PHP_BUILD_DIR} + +# Download and unpack the source code +# --location will follow redirects +# --silent will hide the progress, but also the errors: we restore error messages with --show-error +# --fail makes sure that curl returns an error instead of fetching the 404 page +ARG VERSION_PHP +RUN curl --location --silent --show-error --fail https://downloads.php.net/~edorian/php-${VERSION_PHP}.tar.gz \ + | tar xzC . --strip-components=1 + +# Configure the build +# -fstack-protector-strong : Be paranoid about stack overflows +# -fpic : Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64) +# -fpie : Support Address Space Layout Randomization (see -fpic) +# -O3 : Optimize for fastest binaries possible. +# -I : Add the path to the list of directories to be searched for header files during preprocessing. +# --enable-option-checking=fatal: make sure invalid --configure-flags are fatal errors instead of just warnings +# --enable-ftp: because ftp_ssl_connect() needs ftp to be compiled statically (see https://github.com/docker-library/php/issues/236) +# --enable-mbstring: because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195) +ARG PHP_COMPILATION_FLAGS +RUN ./buildconf --force +RUN CFLAGS="-fstack-protector-strong -fpic -fpie -O3 -I${INSTALL_DIR}/include -I/usr/include -ffunction-sections -fdata-sections" \ + CPPFLAGS="-fstack-protector-strong -fpic -fpie -O3 -I${INSTALL_DIR}/include -I/usr/include -ffunction-sections -fdata-sections" \ + LDFLAGS="-L${INSTALL_DIR}/lib64 -L${INSTALL_DIR}/lib -Wl,-O1 -Wl,--strip-all -Wl,--hash-style=both -pie" \ + PKG_CONFIG_PATH="${INSTALL_DIR}/lib/pkgconfig:${INSTALL_DIR}/lib64/pkgconfig" \ + ./configure \ + --prefix=${INSTALL_DIR} \ + --enable-option-checking=fatal \ + --enable-sockets \ + --with-config-file-path=/opt/bref/etc/php \ + --with-config-file-scan-dir=/opt/bref/etc/php/conf.d:/var/task/php/conf.d \ + --enable-fpm \ + --disable-cgi \ + --enable-cli \ + --disable-phpdbg \ + --with-sodium \ + --with-readline \ + --with-openssl \ + --with-zlib \ + --with-curl \ + --enable-exif \ + --enable-ftp \ + --with-gettext \ + --enable-mbstring \ + --with-pdo-mysql=shared,mysqlnd \ + --with-mysqli \ + --enable-pcntl \ + --with-zip \ + --enable-bcmath \ + --with-pdo-pgsql=shared,${INSTALL_DIR} \ + --enable-intl=shared \ + --enable-soap \ + --with-xsl=${INSTALL_DIR} \ + --with-ffi \ + # necessary for `pecl` to work (to install PHP extensions) + --with-pear \ + # extra compilation flags + ${PHP_COMPILATION_FLAGS} +RUN make -j $(nproc) +# Run `make install` and override PEAR's PHAR URL because pear.php.net is down +RUN set -xe; \ + make install PEAR_INSTALLER_URL='https://github.com/pear/pearweb_phars/raw/master/install-pear-nozlib.phar'; \ + { find ${INSTALL_DIR}/bin ${INSTALL_DIR}/sbin -type f -perm +0111 -exec strip --strip-all '{}' + || true; }; \ + make clean; \ + cp php.ini-production ${INSTALL_DIR}/etc/php/php.ini + + +# Install extensions +# We can install extensions manually or using `pecl` +ENV VERSION_APCU=5.1.24 +RUN pecl install apcu-${VERSION_APCU} + + +# --------------------------------------------------------------- +# Now we copy everything we need for the layers into /bref-layer (which will be used for the real /opt later) +RUN mkdir -p /bref-layer/bin \ +&& mkdir -p /bref-layer/lib \ +&& mkdir -p /bref-layer/bref/extensions \ +&& mkdir -p /bref-layer/bref/ssl + +# Copy the PHP binary +RUN cp ${INSTALL_DIR}/bin/php /bref-layer/bin/php && chmod +x /bref-layer/bin/php + +# Copy all the external PHP extensions +RUN cp $(php -r 'echo ini_get("extension_dir");')/* /bref-layer/bref/extensions/ + +# Copy all the required system libraries from: +# - /lib | /lib64 (system libraries installed with `yum`) +# - /opt/bin | /opt/lib | /opt/lib64 (libraries compiled from source) +# into `/bref-layer` (the temp directory for the future Lambda layer) +COPY --link utils/lib-copy /bref/lib-copy +RUN php /bref/lib-copy/copy-dependencies.php /bref-layer/bin/php /bref-layer/lib +RUN php /bref/lib-copy/copy-dependencies.php /bref-layer/bref/extensions/apcu.so /bref-layer/lib +RUN php /bref/lib-copy/copy-dependencies.php /bref-layer/bref/extensions/intl.so /bref-layer/lib +RUN php /bref/lib-copy/copy-dependencies.php /bref-layer/bref/extensions/pdo_mysql.so /bref-layer/lib +RUN php /bref/lib-copy/copy-dependencies.php /bref-layer/bref/extensions/pdo_pgsql.so /bref-layer/lib + +# Copy the OpenSSL certificates file +RUN cp ${CA_BUNDLE} /bref-layer/bref/ssl/cert.pem + +# Copy the OpenSSL config +RUN cp ${INSTALL_DIR}/bref/ssl/openssl.cnf /bref-layer/bref/ssl/openssl.cnf + + +# --------------------------------------------------------------- +# Start from a clean image to copy only the files we need +FROM public.ecr.aws/lambda/provided:al2-${IMAGE_VERSION_SUFFIX} as isolation + +# We selected the files in /bref-layer, now we copy them to /opt (the real directory for the Lambda layer) +COPY --link --from=build-environment /bref-layer /opt + +COPY --link layers/bootstrap.php /opt/bref/bootstrap.php + + +FROM isolation as function + +COPY --link layers/function/bref.ini /opt/bref/etc/php/conf.d/ + +COPY --link layers/function/bootstrap.sh /opt/bootstrap +# Copy files to /var/runtime to support deploying as a Docker image +COPY --link layers/function/bootstrap.sh /var/runtime/bootstrap +RUN chmod +x /opt/bootstrap && chmod +x /var/runtime/bootstrap + + +# Up until here the entire file has been designed as a top-down reading/execution. +# Everything necessary for the `function` layer has been installed, isolated and +# packaged. Now we'll go back one step and start from the extensions so that we +# can install fpm. Then we'll start the fpm layer and quickly isolate fpm. + +FROM build-environment as fpm-extension + +RUN cp ${INSTALL_DIR}/sbin/php-fpm /bref-layer/bin/php-fpm +RUN php /bref/lib-copy/copy-dependencies.php /bref-layer/bin/php-fpm /bref-layer/lib + + +FROM isolation as fpm + +COPY --link --from=fpm-extension /bref-layer /opt + +COPY --link layers/fpm/bref.ini /opt/bref/etc/php/conf.d/ + +COPY --link layers/fpm/bootstrap.sh /opt/bootstrap +# Copy files to /var/runtime to support deploying as a Docker image +COPY --link layers/fpm/bootstrap.sh /var/runtime/bootstrap +RUN chmod +x /opt/bootstrap && chmod +x /var/runtime/bootstrap + +COPY --link layers/fpm/php-fpm.conf /opt/bref/etc/php-fpm.conf diff --git a/tests/Makefile b/tests/Makefile index 0f0ea452..378255d0 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,6 +1,6 @@ export CPU_PREFIX ?= -test: test-80 test-81 test-82 test-83 test-84 +test: test-80 test-81 test-82 test-83 test-84 test-85 # This rule matches with a wildcard, for example `test-80`. # The `$*` variable will contained the matched part, in this case `80`.