Recompiling PHP for serverless-php and Lambda

Submitted by nigel on Sunday 5th November 2017

The serverless-php git repo contains a pre-compiled PHP executable which is uploaded to AWS Lambda as part of the FaaS deploy. However, and deliberately to keep it lightweight, many PHP extensions are not included in this PHP image. I thought I may get through my development without having to rebuild this image, but alas not! I decided to use the Twig template engine and that has a dependency on the hash() function. I realised something was afoot when my execution failed.

Cloudwatch error diagnostic
Cloudwatch Error
The error was discovered by inspecting my Lambda function run log - you may be able to see able there is a uncaught exception leading to a fatal error.
Fatal error: Uncaught Error: Call to undefined function hash() in /var/task/vendor/twig/twig/lib/Twig/Environment.php:272"
I wasn't aware that hash() required a separate PHP extension, so I checked this on my local copy of PHP 7.1 on my Macbook with
$ php -m | grep hash
Aha! So nothing else for it, we need to add this to the compiled PHP image.
Recompilation of PHP image

Thankfully the serverless-php repo contains two files to aid the recompilation of the PHP image - which is a shell script to run the process, and dockerfile.buildphp which is the configuration for a docker container in which the actual recompilation will occur. 

The dockerfile contains the list of PHP extensions to include - so I added hash to the list
RUN ./configure \
    --enable-static=yes \
    --enable-shared=no \
    --disable-all \
    --enable-json \
    --enable-libxml \
    --enable-mbstring \
    --enable-phar \
    --enable-soap \
    --enable-xml \
    --enable-hash \
    --with-curl \
    --with-gd \
    --with-zlib \
    --with-openssl \
    --without-pear \
Now we need to check the PHP filesize and run the build script - most of the output of this has been cropped since it was copious.
$ ls -las php
49144 -rwxr-xr-x@  1 nigel  staff  25161497  2 Nov 14:03 php
$ chmod +x 
$ ./ 
Build complete.
Don't forget to run 'make test'.
 ---> 7b602edcddb5
Removing intermediate container 6c3cd6936a6d
Successfully built 7b602edcddb5
Successfully tagged php-build:latest
Ok so let's check what we've got:
$ ls -las php
50736 -rwxr-xr-x  1 nigel  staff  25976432  4 Nov 16:34 php
A different size which is encouraging! Now let's deploy and run:
$ sls deploy
API Gateway

If we now run our function from the API Gateway or point a web browser on our assigned URL we get a 200 success! Yey!