Skip to content

Commit d259ec7

Browse files
committed
Refactor the build process into more images
The new `bref/build-php-7X` images will provide users a Docker images where they can compile PHP extensions.
1 parent c69b8be commit d259ec7

File tree

15 files changed

+391
-350
lines changed

15 files changed

+391
-350
lines changed

Makefile

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
SHELL := /bin/bash
2-
TAG = latest
3-
.PHONY: layers
2+
.PHONY: publish layers docker-images
43

54
# Publish the layers on AWS Lambda
65
publish: layers
7-
php publish.php
6+
cd layers ; php publish.php
87

98
# Build the layers
109
layers: export/console.zip export/php-72.zip export/php-73.zip export/php-72-fpm.zip export/php-73-fpm.zip
1110

1211
# The PHP runtimes
13-
export/php%.zip: build
12+
export/php%.zip: docker-images
1413
PHP_VERSION=$$(echo $@ | cut -d'/' -f 2 | cut -d'.' -f 1);\
1514
rm -f $@;\
1615
mkdir export/tmp ; cd export/tmp ;\
@@ -22,14 +21,24 @@ export/console.zip: layers/console/bootstrap
2221
rm -f export/console.zip
2322
cd layers/console && zip ../../export/console.zip bootstrap
2423

25-
# Compile PHP and its extensions
26-
build:
27-
docker build -f ${PWD}/php-intermediary.Dockerfile -t bref/php-72-intermediary:latest $(shell helpers/docker_args.sh versions.ini php72) .
28-
cd layers/fpm ; docker build -t bref/php-72-fpm:$(TAG) --build-arg LAYER_IMAGE=bref/php-72-intermediary:latest . ; cd ../..
29-
cd layers/fpm-dev ; docker build -t bref/php-72-fpm-dev:$(TAG) --build-arg LAYER_IMAGE=bref/php-72-fpm:$(TAG) . ; cd ../..
30-
cd layers/function ; docker build -t bref/php-72:$(TAG) --build-arg LAYER_IMAGE=bref/php-72-intermediary:latest . ; cd ../..
31-
docker build -f ${PWD}/php-intermediary.Dockerfile -t bref/php-73-intermediary:latest $(shell helpers/docker_args.sh versions.ini php73) .
32-
cd layers/fpm ; docker build -t bref/php-73-fpm:$(TAG) --build-arg LAYER_IMAGE=bref/php-73-intermediary:latest . ; cd ../..
33-
cd layers/fpm-dev ; docker build -t bref/php-73-fpm-dev:$(TAG) --build-arg LAYER_IMAGE=bref/php-73-fpm:$(TAG) . ; cd ../..
34-
cd layers/function ; docker build -t bref/php-73:$(TAG) --build-arg LAYER_IMAGE=bref/php-73-intermediary:latest . ; cd ../..
35-
cd layers/web; docker build -t bref/fpm-dev-gateway:$(TAG) . ; cd ../..
24+
# Build Docker images
25+
docker-images:
26+
# Build the base environment (without PHP)
27+
cd base ; docker build --file base.Dockerfile -t bref/tmp/step-1/build-environment .
28+
# Build the `bref/build-php-XX` images
29+
# (build only the first `FROM` section of the Dockerfile)
30+
cd base ; docker build --file php-72.Dockerfile -t bref/build-php-72 --target build-environment .
31+
cd base ; docker build --file php-73.Dockerfile -t bref/build-php-73 --target build-environment .
32+
# Build the whole Dockerfile to generate the cleaned images that will be used in the next step
33+
cd base ; docker build --file php-72.Dockerfile -t bref/tmp/cleaned-build-php-72 .
34+
cd base ; docker build --file php-73.Dockerfile -t bref/tmp/cleaned-build-php-73 .
35+
# - function
36+
cd layers/function ; docker build -t bref/php-72 --build-arg PHP_VERSION=72 .
37+
cd layers/function ; docker build -t bref/php-73 --build-arg PHP_VERSION=73 .
38+
# - fpm
39+
cd layers/fpm ; docker build -t bref/php-72-fpm --build-arg PHP_VERSION=72 .
40+
cd layers/fpm ; docker build -t bref/php-73-fpm --build-arg PHP_VERSION=73 .
41+
# Other Docker images
42+
cd layers/fpm-dev ; docker build -t bref/php-72-fpm-dev --build-arg PHP_VERSION=72 .
43+
cd layers/fpm-dev ; docker build -t bref/php-73-fpm-dev --build-arg PHP_VERSION=73 .
44+
cd layers/web; docker build -t bref/fpm-dev-gateway .

README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,36 @@
11
This directory contains the scripts that create and publish the AWS Lambda runtimes for PHP.
22

33
Read the [runtimes documentation](/docs/runtimes/README.md) to learn more.
4+
5+
## How it works
6+
7+
The scripts are written mainly in `Makefile`.
8+
9+
Multiple Docker images are created:
10+
11+
- `bref/tmp/...` images are created locally and not published online
12+
- `bref/...` images are published on Docker Hub
13+
14+
Workflow:
15+
16+
- 1: Create the `bref/tmp/step-1/build-environment` Docker image.
17+
This image contains everything needed to compile PHP. This image is created standalone because
18+
it is common for each PHP version. The next step involves a different Dockerfile per PHP version.
19+
20+
- 2: Create the `bref/build-php-XX` images.
21+
There is one image per PHP version. These images contain PHP compiled with all its extensions.
22+
It is published so that anyone can use it to compile their own extensions.
23+
It is not the final image because it contains too many things that need to be removed.
24+
25+
- 3: Create the `bref/tmp/cleaned-build-php-XX` images.
26+
There is one image per PHP version. These images contain PHP compiled with all its extensions,
27+
but with all extra files removed. These images do not contain the bootstrap files and PHP config files.
28+
29+
- 4: Create the `bref/php-XX`, `bref/php-XX-fpm`, `bref/php-XX-fpm-dev` images.
30+
There is one image per PHP version. These images contain exactly what will be in the layers in `/opt`.
31+
32+
- 5: Create the layers zip files in the `export/` directory.
33+
We zip the `/opt` directory of each Docker image.
34+
35+
- 6: Publish the layers on AWS.
36+
We upload and publish the layers in every AWS region using the zip files.

base/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
There is one Dockerfile per minor PHP version because each version can have slightly different configuration options.

php-intermediary.Dockerfile renamed to base/base.Dockerfile

Lines changed: 13 additions & 175 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
# The container we build here contains everything needed to compile PHP + PHP.
2-
#
3-
# It can be used as a base to compile extra extensions.
1+
# The container we build here contains everything needed to compile PHP.
42

53

64
# Lambda instances use the amzn-ami-hvm-2018.03.0.20181129-x86_64-gp2 AMI, as
@@ -94,11 +92,11 @@ RUN mkdir -p ${BUILD_DIR} \
9492
# https://github.com/madler/zlib/releases
9593
# Needed for:
9694
# - openssl
95+
# - curl
9796
# - php
9897
# Used By:
9998
# - xml2
100-
ARG zlib
101-
ENV VERSION_ZLIB=${zlib}
99+
ENV VERSION_ZLIB=1.2.11
102100
ENV ZLIB_BUILD_DIR=${BUILD_DIR}/xml2
103101

104102
RUN set -xe; \
@@ -130,9 +128,9 @@ RUN set -xe; \
130128
# Needs:
131129
# - zlib
132130
# Needed by:
131+
# - curl
133132
# - php
134-
ARG openssl
135-
ENV VERSION_OPENSSL=${openssl}
133+
ENV VERSION_OPENSSL=1.1.1a
136134
ENV OPENSSL_BUILD_DIR=${BUILD_DIR}/xml2
137135
ENV CA_BUNDLE_SOURCE="https://curl.haxx.se/ca/cacert.pem"
138136
ENV CA_BUNDLE="${INSTALL_DIR}/ssl/cert.pem"
@@ -173,8 +171,7 @@ RUN set -xe; \
173171
# - OpenSSL
174172
# Needed by:
175173
# - curl
176-
ARG libssh2
177-
ENV VERSION_LIBSSH2=${libssh2}
174+
ENV VERSION_LIBSSH2=1.8.0
178175
ENV LIBSSH2_BUILD_DIR=${BUILD_DIR}/libssh2
179176

180177
RUN set -xe; \
@@ -207,11 +204,10 @@ RUN set -xe; \
207204
# # Needs:
208205
# # - zlib
209206
# # - OpenSSL
210-
# # - curl
207+
# # - libssh2
211208
# # Needed by:
212209
# # - php
213-
ARG curl
214-
ENV VERSION_CURL=${curl}
210+
ENV VERSION_CURL=7.63.0
215211
ENV CURL_BUILD_DIR=${BUILD_DIR}/curl
216212

217213
RUN set -xe; \
@@ -261,8 +257,7 @@ RUN set -xe; \
261257
# - zlib
262258
# Needed by:
263259
# - php
264-
ARG libxml2
265-
ENV VERSION_XML2=${libxml2}
260+
ENV VERSION_XML2=2.9.8
266261
ENV XML2_BUILD_DIR=${BUILD_DIR}/xml2
267262

268263
RUN set -xe; \
@@ -300,8 +295,7 @@ RUN set -xe; \
300295
# https://github.com/nih-at/libzip/releases
301296
# Needed by:
302297
# - php
303-
ARG libzip
304-
ENV VERSION_ZIP=${libzip}
298+
ENV VERSION_ZIP=1.5.1
305299
ENV ZIP_BUILD_DIR=${BUILD_DIR}/zip
306300

307301
RUN set -xe; \
@@ -328,12 +322,11 @@ RUN set -xe; \
328322
###############################################################################
329323
# LIBSODIUM Build
330324
# https://github.com/jedisct1/libsodium/releases
331-
# Uses:
325+
# Needs:
332326
#
333327
# Needed by:
334328
# - php
335-
ARG libsodium
336-
ENV VERSION_LIBSODIUM=${libsodium}
329+
ENV VERSION_LIBSODIUM=1.0.16
337330
ENV LIBSODIUM_BUILD_DIR=${BUILD_DIR}/libsodium
338331

339332
RUN set -xe; \
@@ -363,8 +356,7 @@ RUN set -xe; \
363356
# - OpenSSL
364357
# Needed by:
365358
# - php
366-
ARG postgres
367-
ENV VERSION_POSTGRES=${postgres}
359+
ENV VERSION_POSTGRES=9.6.11
368360
ENV POSTGRES_BUILD_DIR=${BUILD_DIR}/postgres
369361

370362
RUN set -xe; \
@@ -386,164 +378,10 @@ RUN set -xe; cd ${POSTGRES_BUILD_DIR}/src/bin/pg_config && make -j $(nproc) && m
386378
RUN set -xe; cd ${POSTGRES_BUILD_DIR}/src/backend && make generated-headers
387379
RUN set -xe; cd ${POSTGRES_BUILD_DIR}/src/include && make install
388380

389-
###############################################################################
390-
# PHP Build
391-
# https://github.com/php/php-src/releases
392-
# Needs:
393-
# - zlib
394-
# - libxml2
395-
# - openssl
396-
# - readline
397-
# - sodium
398-
399-
ARG php
400-
# Setup Build Variables
401-
ENV VERSION_PHP=${php}
402-
ENV PHP_BUILD_DIR=${BUILD_DIR}/php
403-
404-
RUN set -xe; \
405-
mkdir -p ${PHP_BUILD_DIR}; \
406-
# Download and upack the source code
407-
curl -Ls https://github.com/php/php-src/archive/php-${VERSION_PHP}.tar.gz \
408-
| tar xzC ${PHP_BUILD_DIR} --strip-components=1
409-
410-
# Move into the unpackaged code directory
411-
WORKDIR ${PHP_BUILD_DIR}/
412-
413381
# Install some dev files for using old libraries already on the system
414382
# readline-devel : needed for the --with-libedit flag
415383
# gettext-devel : needed for the --with-gettext flag
416384
# libicu-devel : needed for
417385
# libpng-devel : needed for gd
418386
# libjpeg-devel : needed for gd
419387
RUN LD_LIBRARY_PATH= yum install -y readline-devel gettext-devel libicu-devel libpng-devel libjpeg-devel
420-
421-
# Configure the build
422-
# -fstack-protector-strong : Be paranoid about stack overflows
423-
# -fpic : Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64)
424-
# -fpie : Support Address Space Layout Randomization (see -fpic)
425-
# -O3 : Optimize for fastest binaries possible.
426-
# -I : Add the path to the list of directories to be searched for header files during preprocessing.
427-
# --enable-option-checking=fatal: make sure invalid --configure-flags are fatal errors instead of just warnings
428-
# --enable-ftp: because ftp_ssl_connect() needs ftp to be compiled statically (see https://github.com/docker-library/php/issues/236)
429-
# --enable-mbstring: because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195)
430-
# --enable-maintainer-zts: build PHP as ZTS (Zend Thread Safe) to be able to use pthreads
431-
# --with-zlib and --with-zlib-dir: See https://stackoverflow.com/a/42978649/245552
432-
# --enable-opcache-file: allows to use the `opcache.file_cache` option
433-
#
434-
RUN set -xe \
435-
&& ./buildconf --force \
436-
&& CFLAGS="-fstack-protector-strong -fpic -fpie -O3 -I${INSTALL_DIR}/include -I/usr/include -ffunction-sections -fdata-sections" \
437-
CPPFLAGS="-fstack-protector-strong -fpic -fpie -O3 -I${INSTALL_DIR}/include -I/usr/include -ffunction-sections -fdata-sections" \
438-
LDFLAGS="-L${INSTALL_DIR}/lib64 -L${INSTALL_DIR}/lib -Wl,-O1 -Wl,--strip-all -Wl,--hash-style=both -pie" \
439-
./configure \
440-
--build=x86_64-pc-linux-gnu \
441-
--prefix=${INSTALL_DIR} \
442-
--enable-option-checking=fatal \
443-
--enable-maintainer-zts \
444-
--enable-sockets \
445-
--with-config-file-path=${INSTALL_DIR}/etc/php \
446-
--with-config-file-scan-dir=${INSTALL_DIR}/etc/php/conf.d:/var/task/php/conf.d \
447-
--enable-fpm \
448-
--disable-cgi \
449-
--enable-cli \
450-
--disable-phpdbg \
451-
--disable-phpdbg-webhelper \
452-
--with-sodium \
453-
--with-readline \
454-
--with-openssl \
455-
--with-zlib=${INSTALL_DIR} \
456-
--with-zlib-dir=${INSTALL_DIR} \
457-
--with-curl \
458-
--enable-exif \
459-
--enable-ftp \
460-
--with-gettext \
461-
--enable-mbstring \
462-
--with-pdo-mysql=shared,mysqlnd \
463-
--with-mysqli \
464-
--enable-pcntl \
465-
--enable-zip \
466-
--enable-bcmath \
467-
--with-pdo-pgsql=shared,${INSTALL_DIR} \
468-
--enable-intl=shared \
469-
--enable-opcache-file \
470-
--enable-soap \
471-
--with-gd \
472-
--with-png-dir=${INSTALL_DIR} \
473-
--with-jpeg-dir=${INSTALL_DIR}
474-
RUN make -j $(nproc)
475-
# Run `make install` and override PEAR's PHAR URL because pear.php.net is down
476-
RUN set -xe; \
477-
make install PEAR_INSTALLER_URL='https://github.com/pear/pearweb_phars/raw/master/install-pear-nozlib.phar'; \
478-
{ find ${INSTALL_DIR}/bin ${INSTALL_DIR}/sbin -type f -perm +0111 -exec strip --strip-all '{}' + || true; }; \
479-
make clean; \
480-
cp php.ini-production ${INSTALL_DIR}/etc/php/php.ini
481-
482-
RUN pecl install mongodb
483-
RUN pecl install redis
484-
RUN pecl install APCu
485-
486-
ENV PTHREADS_BUILD_DIR=${BUILD_DIR}/pthreads
487-
488-
# Build from master because there are no pthreads release compatible with PHP 7.3
489-
RUN set -xe; \
490-
mkdir -p ${PTHREADS_BUILD_DIR}/bin; \
491-
curl -Ls https://github.com/krakjoe/pthreads/archive/master.tar.gz \
492-
| tar xzC ${PTHREADS_BUILD_DIR} --strip-components=1
493-
494-
WORKDIR ${PTHREADS_BUILD_DIR}/
495-
496-
RUN set -xe; \
497-
phpize \
498-
&& ./configure \
499-
&& make \
500-
&& make install
501-
502-
503-
# Strip all the unneeded symbols from shared libraries to reduce size.
504-
RUN find ${INSTALL_DIR} -type f -name "*.so*" -o -name "*.a" -exec strip --strip-unneeded {} \;
505-
RUN find ${INSTALL_DIR} -type f -executable -exec sh -c "file -i '{}' | grep -q 'x-executable; charset=binary'" \; -print|xargs strip --strip-all
506-
507-
# Cleanup all the binaries we don't want.
508-
RUN find /opt/bref/bin -mindepth 1 -maxdepth 1 ! -name "php" ! -name "pecl" -exec rm {} \+
509-
510-
# Cleanup all the files we don't want either
511-
# We do not support running pear functions in Lambda
512-
RUN rm -rf /opt/bref/lib/php/PEAR \
513-
rm -rf /opt/bref/share/doc \
514-
rm -rf /opt/bref/share/man \
515-
rm -rf /opt/bref/share/gtk-doc \
516-
rm -rf /opt/bref/include \
517-
rm -rf /opt/bref/lib/php/test \
518-
rm -rf /opt/bref/lib/php/doc \
519-
rm -rf /opt/bref/lib/php/docs \
520-
rm -rf /opt/bref/tests \
521-
rm -rf /opt/bref/doc \
522-
rm -rf /opt/bref/docs \
523-
rm -rf /opt/bref/man \
524-
rm -rf /opt/bref/www \
525-
rm -rf /opt/bref/cfg \
526-
rm -rf /opt/bref/libexec \
527-
rm -rf /opt/bref/var \
528-
rm -rf /opt/bref/data
529-
530-
# Symlink all our binaries into /opt/bin so that Lambda sees them in the path.
531-
RUN mkdir -p /opt/bin
532-
RUN ln -s /opt/bref/bin/* /opt/bin
533-
RUN ln -s /opt/bref/sbin/* /opt/bin
534-
535-
536-
# Now we get rid of everything that is unnecessary. All the build tools, source code, and anything else
537-
# that might have created intermediate layers for docker. Back to base AmazonLinux we started with.
538-
FROM amazonlinux:2018.03
539-
ENV INSTALL_DIR="/opt/bref"
540-
ENV PATH="/opt/bin:${PATH}" \
541-
LD_LIBRARY_PATH="${INSTALL_DIR}/lib64:${INSTALL_DIR}/lib"
542-
543-
RUN mkdir -p /opt
544-
# Copy everything we built above into the same dir on the base AmazonLinux container.
545-
COPY --from=0 /opt /opt
546-
547-
# Install zip: we will need it later to create the layers as zip files
548-
RUN LD_LIBRARY_PATH= yum -y install zip
549-
WORKDIR /var/task

0 commit comments

Comments
 (0)