Skip to content

Commit e2e2625

Browse files
committed
feat: add support for php 8.0
1 parent 88d726b commit e2e2625

File tree

6 files changed

+272
-2
lines changed

6 files changed

+272
-2
lines changed

.github/workflows/main.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ jobs:
3636
strategy:
3737
fail-fast: false
3838
matrix:
39-
php-versions: ['7.2', '7.3', '7.4']
39+
php-versions: ['7.2', '7.3', '7.4', '8.0']
4040
steps:
4141
- name: Checkout code
4242
uses: actions/checkout@v2

runtime/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
SHELL := /bin/bash
22
.PHONY: build build-images publish
33

4-
build: build-php-72.zip build-php-73.zip build-php-74.zip
4+
build: build-php-72.zip build-php-73.zip build-php-74.zip build-php-80.zip
55

66
build-php%.zip: build-images
77
PHP_VERSION=$$(echo $@ | cut -d'.' -f 1 | cut -d'-' -f 2,3); \
@@ -15,6 +15,7 @@ build-images:
1515
cd php-72 ; docker build -t ymir/runtime/php-72 .
1616
cd php-73 ; docker build -t ymir/runtime/php-73 .
1717
cd php-74 ; docker build -t ymir/runtime/php-74 .
18+
cd php-80 ; docker build -t ymir/runtime/php-80 .
1819

1920
publish-images: publish-php-72 publish-php-73 publish-php-74
2021

runtime/php-80/Dockerfile

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
FROM ymir/runtime/base as php-build
2+
3+
4+
###############################################################################
5+
# Oniguruma
6+
# This library is not packaged in PHP since PHP 7.4.
7+
# See https://github.com/php/php-src/blob/43dc7da8e3719d3e89bd8ec15ebb13f997bbbaa9/UPGRADING#L578-L581
8+
# We do not install the system version because I didn't manage to make it work...
9+
# Ideally we shouldn't compile it ourselves.
10+
# https://github.com/kkos/oniguruma/releases
11+
# Needed by:
12+
# - php mbstring
13+
ENV VERSION_ONIG=6.9.6
14+
ENV ONIG_BUILD_DIR=${BUILD_DIR}/oniguruma
15+
RUN set -xe; \
16+
mkdir -p ${ONIG_BUILD_DIR}; \
17+
curl -Ls https://github.com/kkos/oniguruma/releases/download/v${VERSION_ONIG}/onig-${VERSION_ONIG}.tar.gz \
18+
| tar xzC ${ONIG_BUILD_DIR} --strip-components=1
19+
WORKDIR ${ONIG_BUILD_DIR}/
20+
RUN set -xe; \
21+
./configure --prefix=${INSTALL_DIR}; \
22+
make -j $(nproc); \
23+
make install
24+
25+
26+
ENV PHP_BUILD_DIR=${BUILD_DIR}/php
27+
RUN set -xe; \
28+
mkdir -p ${PHP_BUILD_DIR}; \
29+
# Download and upack the source code
30+
curl -Ls https://github.com/php/php-src/archive/php-8.0.10.tar.gz \
31+
| tar xzC ${PHP_BUILD_DIR} --strip-components=1
32+
# Move into the unpackaged code directory
33+
WORKDIR ${PHP_BUILD_DIR}/
34+
35+
# Configure the build
36+
# -fstack-protector-strong : Be paranoid about stack overflows
37+
# -fpic : Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64)
38+
# -fpie : Support Address Space Layout Randomization (see -fpic)
39+
# -O3 : Optimize for fastest binaries possible.
40+
# -I : Add the path to the list of directories to be searched for header files during preprocessing.
41+
# --enable-option-checking=fatal: make sure invalid --configure-flags are fatal errors instead of just warnings
42+
# --enable-ftp: because ftp_ssl_connect() needs ftp to be compiled statically (see https://github.com/docker-library/php/issues/236)
43+
# --enable-mbstring: because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195)
44+
# --enable-maintainer-zts: build PHP as ZTS (Zend Thread Safe) to be able to use pthreads
45+
# --with-zlib and --with-zlib-dir: See https://stackoverflow.com/a/42978649/245552
46+
# --with-pear: necessary for `pecl` to work (to install PHP extensions)
47+
#
48+
RUN set -xe \
49+
&& ./buildconf --force \
50+
&& CFLAGS="-fstack-protector-strong -fpic -fpie -O3 -I${INSTALL_DIR}/include -I/usr/include -ffunction-sections -fdata-sections" \
51+
CPPFLAGS="-fstack-protector-strong -fpic -fpie -O3 -I${INSTALL_DIR}/include -I/usr/include -ffunction-sections -fdata-sections" \
52+
LDFLAGS="-L${INSTALL_DIR}/lib64 -L${INSTALL_DIR}/lib -Wl,-O1 -Wl,--strip-all -Wl,--hash-style=both -pie" \
53+
./configure \
54+
--build=x86_64-pc-linux-gnu \
55+
--prefix=${INSTALL_DIR} \
56+
--enable-option-checking=fatal \
57+
--enable-sockets \
58+
--with-config-file-path=${INSTALL_DIR}/etc/php \
59+
--with-config-file-scan-dir=${INSTALL_DIR}/etc/php/conf.d:/var/task/php/conf.d \
60+
--enable-fpm \
61+
--disable-cgi \
62+
--enable-cli \
63+
--disable-phpdbg \
64+
--disable-phpdbg-webhelper \
65+
--with-sodium \
66+
--with-readline \
67+
--with-openssl \
68+
--with-zlib=${INSTALL_DIR} \
69+
--with-zlib-dir=${INSTALL_DIR} \
70+
--with-curl \
71+
--enable-exif \
72+
--enable-ftp \
73+
--with-gettext \
74+
--enable-mbstring \
75+
--with-pdo-mysql=shared,mysqlnd \
76+
--with-mysqli \
77+
--enable-pcntl \
78+
--with-zip \
79+
--enable-bcmath \
80+
--enable-intl=shared \
81+
--enable-soap \
82+
--with-xsl=${INSTALL_DIR} \
83+
--with-pear
84+
RUN make -j $(nproc)
85+
# Run `make install` and override PEAR's PHAR URL because pear.php.net is down
86+
RUN set -xe; \
87+
make install PEAR_INSTALLER_URL='https://github.com/pear/pearweb_phars/raw/master/install-pear-nozlib.phar'; \
88+
{ find ${INSTALL_DIR}/bin ${INSTALL_DIR}/sbin -type f -perm +0111 -exec strip --strip-all '{}' + || true; }; \
89+
make clean; \
90+
cp php.ini-production ${INSTALL_DIR}/etc/php/php.ini
91+
92+
# Install extensions using pecl
93+
RUN pecl install APCu
94+
RUN pecl install igbinary
95+
RUN pecl install zstd
96+
97+
# Build extensions
98+
WORKDIR ${IMAGICK_BUILD_DIR}
99+
RUN set -xe; \
100+
pecl download imagick-${VERSION_IMAGICK_EXTENSION}; \
101+
tar xzf imagick-${VERSION_IMAGICK_EXTENSION}.tgz
102+
WORKDIR ${IMAGICK_BUILD_DIR}/imagick-${VERSION_IMAGICK_EXTENSION}
103+
RUN set -xe; \
104+
phpize; \
105+
./configure --with-imagick=${INSTALL_DIR}; \
106+
make -j $(nproc); \
107+
make install;
108+
109+
WORKDIR ${REDIS_BUILD_DIR}
110+
RUN set -xe; \
111+
pecl download redis-${VERSION_REDIS_EXTENSION}; \
112+
tar xzf redis-${VERSION_REDIS_EXTENSION}.tgz
113+
WORKDIR ${REDIS_BUILD_DIR}/redis-${VERSION_REDIS_EXTENSION}
114+
RUN set -xe; \
115+
phpize; \
116+
./configure --enable-redis-igbinary --enable-redis-zstd; \
117+
make && make install;
118+
119+
# Install Composer
120+
RUN curl -sS https://getcomposer.org/installer | ${INSTALL_DIR}/bin/php -- --install-dir=${INSTALL_DIR}/bin/ --filename=composer
121+
122+
# Symlink all our binaries into /opt/bin so that Lambda sees them in the path.
123+
RUN mkdir -p /opt/bin \
124+
&& cd /opt/bin \
125+
&& ln -s ../ymir/bin/* . \
126+
&& ln -s ../ymir/sbin/* .
127+
128+
# Remove extra files to make the layers as slim as possible
129+
COPY clean.sh /tmp
130+
RUN /tmp/clean.sh && rm /tmp/clean.sh
131+
132+
# Copy config files
133+
COPY php.ini ${INSTALL_DIR}/etc/php/conf.d
134+
COPY php-fpm.conf ${INSTALL_DIR}/etc/php-fpm.d
135+
136+
# Build PHP runtime
137+
RUN git clone https://github.com/ymirapp/php-runtime.git /tmp/runtime-build \
138+
&& cd /tmp/runtime-build \
139+
&& git checkout tags/v1.0.0 \
140+
&& cd /opt \
141+
&& cp -R /tmp/runtime-build/composer.json /tmp/runtime-build/composer.lock /tmp/runtime-build/runtime/bootstrap /tmp/runtime-build/runtime/runtime.php /tmp/runtime-build/src ./ \
142+
&& chmod 0555 /opt/bootstrap /opt/runtime.php \
143+
&& composer install --no-dev
144+
145+
# Now we start back from a clean image.
146+
# We get rid of everything that is unnecessary (build tools, source code, and anything else
147+
# that might have created intermediate layers for docker) by copying online the /opt directory.
148+
FROM public.ecr.aws/lambda/provided:al2
149+
ENV PATH="/opt/bin:${PATH}" \
150+
LD_LIBRARY_PATH="/opt/ymir/lib64:/opt/ymir/lib"
151+
152+
# Copy everything we built above into the same dir on the base AmazonLinux container.
153+
COPY --from=php-build /opt /opt
154+
155+
# Needed for building the layer
156+
COPY --from=php-build /usr/lib64 /usr/lib64

runtime/php-80/clean.sh

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# ------------------------------------------
2+
# This script cleans extra files from /opt
3+
# to keep the layers as small as possible.
4+
# ------------------------------------------
5+
6+
# Stop on error
7+
set -e
8+
# Treat unset variables and parameters as an error.
9+
set -u
10+
11+
# Strip all the unneeded symbols from shared libraries to reduce size.
12+
find /opt/ymir -type f -name "*.so*" -exec strip --strip-unneeded {} \;
13+
find /opt/ymir -type f -name "*.a"|xargs rm
14+
find /opt/ymir -type f -name "*.la"|xargs rm
15+
find /opt/ymir -type f -name "*.dist"|xargs rm
16+
find /opt/ymir -type f -executable -exec sh -c "file -i '{}' | grep -q 'x-executable; charset=binary'" \; -print|xargs strip --strip-all
17+
18+
# Cleanup all the binaries we don't want.
19+
find /opt/ymir/sbin -mindepth 1 -maxdepth 1 ! -name "composer" ! -name "php" ! -name "php-fpm" -exec rm {} \+
20+
find /opt/ymir/bin -mindepth 1 -maxdepth 1 ! -name "composer" ! -name "php" ! -name "php-fpm" -exec rm {} \+
21+
find /opt/bin -mindepth 1 -maxdepth 1 ! -name "composer" ! -name "php" ! -name "php-fpm" -exec rm {} \+
22+
23+
# Cleanup all the files we don't want either
24+
# We do not support running pear functions in Lambda
25+
rm -rf /opt/ymir/lib/php/PEAR
26+
rm -rf /opt/ymir/share
27+
rm -rf /opt/ymir/include
28+
rm -rf /opt/ymir/{lib,lib64}/pkgconfig
29+
rm -rf /opt/ymir/{lib,lib64}/cmake
30+
rm -rf /opt/ymir/lib/xml2Conf.sh
31+
find /opt/ymir/lib/php -mindepth 1 -maxdepth 1 -type d -a ! -name "extensions" -exec rm -rf {} \;
32+
find /opt/ymir/lib/php -mindepth 1 -maxdepth 1 -type f -exec rm -rf {} \;
33+
rm -rf /opt/ymir/lib/php/test
34+
rm -rf /opt/ymir/lib/php/doc
35+
rm -rf /opt/ymir/lib/php/docs
36+
rm -rf /opt/ymir/tests
37+
rm -rf /opt/ymir/doc
38+
rm -rf /opt/ymir/docs
39+
rm -rf /opt/ymir/man
40+
rm -rf /opt/ymir/php
41+
rm -rf /opt/ymir/www
42+
rm -rf /opt/ymir/cfg
43+
rm -rf /opt/ymir/libexec
44+
rm -rf /opt/ymir/var
45+
rm -rf /opt/ymir/data

runtime/php-80/php-fpm.conf

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
; Logging anywhere on disk doesn't make sense on lambda since instances are ephemeral
2+
error_log = /dev/null
3+
pid = /tmp/.ymir/php-fpm.pid
4+
; Log above warning because PHP-FPM logs useless notices
5+
; We must comment this flag else uncaught exceptions/fatal errors are not reported in the logs!
6+
; TODO: report that to the PHP bug tracker
7+
;log_level = 'warning'
8+
9+
[default]
10+
pm = static
11+
; We only need one child because a lambda can process only one request at a time
12+
pm.max_children = 1
13+
listen = /tmp/.ymir/php-fpm.sock
14+
; Allows PHP processes to access the lambda's environment variables
15+
clear_env = no
16+
; Forward stderr of PHP processes to stderr of PHP-FPM (so that it can be sent to cloudwatch)
17+
catch_workers_output = yes
18+
; New PHP 7.3 option that disables a verbose log prefix
19+
decorate_workers_output = no
20+
; Limit the number of core dump logs to 1 to avoid filling up the /tmp disk
21+
rlimit_core = 1

runtime/php-80/php.ini

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
; Do not display errors in production because with PHP-FPM that means
2+
; errors will be output in the HTTP response
3+
display_errors=0
4+
5+
; Since PHP 7.4 the default value is E_ALL
6+
; We override it to set the recommended configuration value for production.
7+
; See https://github.com/php/php-src/blob/d91abf76e01a3c39424e8192ad049f473f900936/php.ini-production#L463
8+
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
9+
10+
memory_limit=3008M
11+
12+
opcache.enable=1
13+
opcache.enable_cli=1
14+
15+
; Skip this check to save a bit
16+
opcache.validate_permission=0
17+
18+
; The code is readonly on lambdas so it never changes
19+
opcache.validate_timestamps=0
20+
21+
; Set sane values, modern PHP applications have higher needs than opcache's defaults
22+
; See https://tideways.com/profiler/blog/fine-tune-your-opcache-configuration-to-avoid-caching-suprises
23+
opcache.memory_consumption=128
24+
opcache.max_accelerated_files=10000
25+
opcache.max_wasted_percentage=10
26+
27+
extension=apcu.so
28+
extension=igbinary.so
29+
extension=imagick.so
30+
extension=intl.so
31+
extension=pdo_mysql.so
32+
extension=redis.so
33+
extension=zstd.so
34+
zend_extension=opcache.so
35+
36+
; This directive determines which super global arrays are registered when PHP
37+
; starts up. G,P,C,E & S are abbreviations for the following respective super
38+
; globals: GET, POST, COOKIE, ENV and SERVER.
39+
; We explicitly populate all variables else ENV is not populated by default.
40+
variables_order="EGPCS"
41+
42+
; The lambda environment is not compatible with fastcgi_finish_request
43+
disable_functions=fastcgi_finish_request
44+
45+
; API Gateway has a timeout of 29 seconds. Setting this to 28 will give PHP some
46+
; time to properly finish up its resources and flush logs to CloudWatch.
47+
max_execution_time=28

0 commit comments

Comments
 (0)