DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
  1. DZone
  2. Software Design and Architecture
  3. Cloud Architecture
  4. Using img2lambda to Publish Your Serverless PHP layer

Using img2lambda to Publish Your Serverless PHP layer

We investigate a handy new tool to help publish your local PHP runtime layers from Docker to AWS Lambda.

Rob Allen user avatar by
Rob Allen
·
Feb. 04, 19 · Presentation
Like (1)
Save
Tweet
Share
5.31K Views

Join the DZone community and get the full member experience.

Join For Free

This interesting tweet by Clare Liguori came to my attention last week:

This new img2lambda tool will take the layers of a Docker container and convert them to AWS layers for use in Lambda.

I poked around with Clare's example and updated my lambda-php project in order to understand how it works. I also rewrote my runtime's bootstrap to make it clearer.

The clever thing from my point of view is that you can build your PHP runtime layer locally using Docker and then publish the layers to AWS for use in your Lambda functions. This means you can now use the layer in different projects and have them all reference the same PHP runtime.

The Magic of Docker

This is all done with the magic of Docker. Specifically, we create a Dockerfile that creates containers:

  • A container to build the PHP binary
  • A container containing the layers that img2lambda will upload to AWS

Simplified, it looks like this:

# Build PHP in the Lambda container
FROM amazonlinux:2017.03.1.20170812 as builder

# PHP version of create
ARG ver="7.3.1"

RUN sed -i 's;^releasever.*;releasever=2017.03;;' /etc/yum.conf && \
    yum clean all && \
    yum install -y autoconf bison gcc gcc-c++ make libcurl-devel {etc}

RUN curl -sL https://github.com/php/php-src/archive/php-${ver}.tar.gz | tar -xvz && \
    cd php-src-php-${ver} && \
    ./buildconf --force && \
    ./configure --prefix=/opt/php/ --with-openssl --with-curl --{etc} && \
    make install && \
    /opt/php/bin/php -v

# copy php binary into /runtime/bin/php
RUN mkdir -p /runtime/bin && \
    cp /opt/php/bin/php /runtime/bin/php

# copy bootstrap files into /runtime
COPY src/* /runtime/


# Create runtime container for use with img2lambda
FROM lambci/lambda:provided as runtime

 COPY --from=builder /runtime /opt/


The first part download and compiles the PHP binary and puts it into /runtime/bin/php and also copies in the bootstrap files required to make the layer act as a Lambda runtime.

The second part simply copies all the files in /runtime in the first container into a new container. This new container contains a single layer, which is our PHP runtime.

To build it, we do:

$ docker build -t lambda-php-runtime


The tag name can be anything.

Create the Layer in AWS

To create the AWS layer, we use img2lambda:

$ img2lambda -i lambda-php-runtime:latest -r eu-west-2 -n lambda-php73


This tool will find the layer in the runtime container, upload it to eu-west2, and then store the identifier in output/layers.json, which looks like this:

[
  "arn:aws:lambda:eu-west-2:66...06:layer:lambda-php73-sha256-e3c4...2e618b:1"
]


Using the Serverless Framework

You can take the ARN number and use it for your actions in serverless.yml, like this:

functions:
  hello:
    handler: handler.hello
    layers: 
      - "arn:aws:lambda:eu-west-2:66...06:layer:lambda-php73-sha256-e3c4...2e618b:1"


This is the way that we can re-use our PHP runtime in all our actions across multiple projects.

Serverless also allows you to import data from JSON files into your serverless.yml file, so you can also do:

functions:
  hello:
    handler: handler.hello    # {file name}.{function name}. In this case: hello() in handler.php
    layers:
      ${file(../php-runtime/output/layers.json)


This has the advantage that when you re-build and upload PHP runtime layer, your project picks it up, which could also be convenient.

Testing Locally

One of the benefits of building the runtime in Docker is that we can run it locally for testing our Lambda function. As our runtime container inherits from lambci/lambda:provided, we get an environment that looks very much like Lambda itself.

To test locally, we use another container and inherits from our runtime one and copies in the PHP files for our function. The Dockerfile looks something like this:

FROM lambda-php-runtime as function

COPY handler.php /var/task/src/handler.php


We create our container:

$ docker build -t lambda-php-test 


And then, we can test it:

$ docker run lambda-php-test handler.hello '{"name": "Rob"}'


To get the output:

START RequestId: 52fdfc07-2182-154f-163f-5f0f9a621d72 Version: $LATEST
{"msg":"hello from PHP 7.3.1","eventData":{"name":"world"}}
END RequestId: 52fdfc07-2182-154f-163f-5f0f9a621d72
REPORT RequestId: 52fdfc07-2182-154f-163f-5f0f9a621d72Init Duration: 144.73 msDuration: 6.31 msBilled Duration: 100 msMemory Size: 1536 MBMax Memory Used: 23 MB


Very convenient.

Summary

I really like the separation of publishing the PHP runtime layer from my project and the ability to reuse this layer in multiple projects is magic.

Ideally, I would like to be able to update the layer with a new patch release of PHP and use the ARN so that all my functions don't need to be re-deployed. Maybe I'll look at how that can be done at some point.

Have a play with my lambda-php project to see if this approach works for you. Also, check out Bref for another way to run PHP on Lambda.

PHP Docker (software)

Published at DZone with permission of Rob Allen, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Utilize OpenAI API to Extract Information From PDF Files
  • Continuous Development: Building the Thing Right, to Build the Right Thing
  • The Role of Data Governance in Data Strategy: Part II
  • Why It Is Important To Have an Ownership as a DevOps Engineer

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: