Compiling PHP for use on Lambda
Lambda Docker Containers
AWS Lambda is powered by Docker containers. If you provide a script, Lambda will download the script and execute it within a Docker container. If you provide a zip file, Lambda will download the zip and execute the contents within a Docker contianer.
The docker containers Lambda runs are Amazon Linux. Amazon Lambda does not natively support php, however we can use php if we compile a static single-binary version which can be called by another language that Lambda does support, like NodeJS.
var args = ['handler.php', JSON.stringify(event), JSON.stringify(contextData)];
var options = {stdio: ['pipe', 'pipe', 'pipe', 'pipe']};
var proc = child_process.spawn("./php", args, options);
How to compile php 5.6.6 for Lambda
There is an Amazon Linux docker container available. We will download the docker container and use that to compile our php binary.
docker pull amazonlinux:2016.09
Amazon Linux contains the latest security fixes for OpenSSL. However, as of January 2018, the Docker Images used in Lambda do not contain the latest OpenSSL packages. This is a problem because while you will be able to compile your php binary for use with Lambda, you will not be able to run it. To make matters worse, Amazon has removed the previous version of the OpenSSL package from their repositories. So we need a version of PHP compiled against the previous OpenSSL release so that it will run inside of the AWS Lambda docker container.
Getting OpenSSL 1.0.1k
The package is not available in the Amazon Linux Mirrors
Ideally you could solve this issue by downgrading the openssl package and using the yum versionlock plugin to keep the package from being upgraded.
yum install yum-plugin-versionlock
yum versionlock openssl-1.0.1k
yum versionlock openssl-devel-1.0.1k
Unfortunately the outdated openssl-1.0.1k packages are no longer available in the Amazon Linux mirrors. Amazon’s practice of purging the outdated packages from the mirror is not a bad practice, but it does prevent us from getting the package we need to build against.
Using a CentOS package
Luckily Amazon Linux is based on RHEL, so we can substitute a package from CentOS for a relative amount of compatibility. Amazon does upgrade a LOT of the base system so this little trick doesn’t always work. However, in this instance, we are able to locate the packages on http://rpm.pbone.net/
Search results for openssl-libs-1.0.1k-8cnt7.x86_64.rpm :
Filename Distribution File size
openssl-libs-1.0.1k-8cnt7.x86_64.rpm CentOS 7 951 kB
openssl-libs-1.0.1k-8cnt7.x86_64.rpm CentOS Other 951 kB
Build PHP for compatibility with Lambda
##
## Download Bison
##
wget http://ftp.gnu.org/gnu/bison/bison-2.6.4.tar.gz
##
## Download OpenSSL 1.0.1k which is still used by the Lambda Docker image
##
wget ftp://ftp.pbone.net/mirror/rnd.rajven.net/centos/7.0.1406/os/x86_64/openssl-libs-1.0.1k-8cnt7.x86_64.rpm
wget ftp://ftp.pbone.net/mirror/rnd.rajven.net/centos/7/os/x86_64/openssl-devel-1.0.1k-8cnt7.x86_64.rpm
##
## Download the latest PHP
##
PHP_VERSION="php-5.6.33"
wget https://github.com/php/php-src/archive/$PHP_VERSION.tar.gz
tar zxf $PHP_VERSION.tar.gz
##
## Download APD which is used to rewrite
## some PHP functions for use with Lambda
##
cd php-src-$PHP_VERSION
git clone https://github.com/ZeWaren/pecl-apd.git
mv pecl-apd ext/apd
cd ..
##
## Start Amazon Linux Docker Container
##
docker run \
-e PHP_VERSION="${PHP_VERSION}" \
-v $(pwd):/srv \
-ti \
amazonlinux \
/bin/bash
##
## Install dependencies needed for compiling PHP
##
yum install -y \
autoconf \
automake \
libtool \
wget \
git \
m4 \
re2c \
libxml2-devel \
openssl-devel \
libpng-devel \
libjpeg-devel \
mysql \
curl-devel
##
## Install OpenSSL 1.0.1k
##
cd /srv
rpm -ivh --force --nodeps openssl-libs-1.0.1k-8cnt7.x86_64.rpm
rpm -ivh --force --nodeps openssl-devel-1.0.1k-8cnt7.x86_64.rpm
##
## Compile Bison
##
tar -xvzf bison-2.6.4.tar.gz
cd bison-2.6.4
./configure && make && make install
cd /srv
##
## Build PHP
##
cd php-src-$PHP_VERSION
./buildconf --force
ls /lib64/libcrypt*
./configure \
--enable-static=yes \
--enable-shared=no \
--disable-all \
--enable-apd \
--enable-dom \
--enable-filter \
--enable-hash \
--enable-json \
--enable-libxml \
--enable-mbstring \
--enable-phar \
--enable-pdo \
--enable-simplexml \
--enable-soap \
--enable-xml \
--enable-xmlwriter \
--enable-zip \
--with-png-dir=/usr/lib64/libpng12.so.0.49.0 \
--with-jpeg-dir=/usr/lib64/libjpeg.so.62.0.0 \
--with-curl \
--with-gd \
--with-iconv \
--with-mysql \
--with-mysqli \
--with-pdo-mysql \
--with-xmlrpc \
--with-zlib \
--with-openssl \
--without-pear \
--enable-ctype \
--enable-fileinfo
make -j 5
cp ./sapi/cli/php /srv/
The php binary for use with Lambda is now ready.