├── .gitignore ├── .travis.yml ├── Dockerfile.BuildPHP ├── Dockerfile.TestLambdaApp ├── LICENSE ├── README.md ├── build_php_7.sh ├── img └── aws-lambda.settings.png ├── index.js ├── index.php ├── package.json └── test └── index.test.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Node template 3 | # Logs 4 | logs 5 | *.log 6 | 7 | # Runtime data 8 | pids 9 | *.pid 10 | *.seed 11 | 12 | # Directory for instrumented libs generated by jscoverage/JSCover 13 | lib-cov 14 | 15 | # Coverage directory used by tools like istanbul 16 | coverage 17 | 18 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 19 | .grunt 20 | 21 | # node-waf configuration 22 | .lock-wscript 23 | 24 | # Compiled binary addons (http://nodejs.org/api/addons.html) 25 | build/Release 26 | 27 | # Dependency directory 28 | # https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git 29 | node_modules 30 | 31 | 32 | ### OSX template 33 | .DS_Store 34 | .AppleDouble 35 | .LSOverride 36 | 37 | # Icon must end with two \r 38 | Icon 39 | 40 | # Thumbnails 41 | ._* 42 | 43 | # Files that might appear in the root of a volume 44 | .DocumentRevisions-V100 45 | .fseventsd 46 | .Spotlight-V100 47 | .TemporaryItems 48 | .Trashes 49 | .VolumeIcon.icns 50 | 51 | # Directories potentially created on remote AFP share 52 | .AppleDB 53 | .AppleDesktop 54 | Network Trash Folder 55 | Temporary Items 56 | .apdisk 57 | 58 | php 59 | .idea 60 | aws-lambda-php.iml -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | 3 | node_js: 4 | - "4.3" 5 | 6 | sudo: required 7 | 8 | services: 9 | - docker 10 | 11 | before_install: 12 | - sh build_php_7.sh 13 | 14 | script: 15 | - npm install 16 | - npm test -------------------------------------------------------------------------------- /Dockerfile.BuildPHP: -------------------------------------------------------------------------------- 1 | # Compile PHP 7.1.0RC5 with static linked dependencies 2 | # to create a single running binary 3 | 4 | FROM ubuntu 5 | 6 | ARG PHP_VERSION 7 | 8 | RUN apt-get update && apt-get install -y \ 9 | git \ 10 | autoconf \ 11 | wget \ 12 | libcurl4-openssl-dev \ 13 | libjpeg-dev \ 14 | libpng-dev \ 15 | libxpm-dev \ 16 | libmysqlclient-dev \ 17 | libpq-dev \ 18 | libicu-dev \ 19 | libfreetype6-dev \ 20 | libldap2-dev \ 21 | libxslt-dev \ 22 | build-essential \ 23 | libssl-dev \ 24 | libgmp-dev \ 25 | libpspell-dev \ 26 | librecode-dev \ 27 | php-mysql 28 | 29 | RUN git clone -b $PHP_VERSION https://github.com/php/php-src /php-src/ 30 | 31 | WORKDIR /php-src 32 | 33 | RUN ln -s /usr/include/x86_64-linux-gnu/gmp.h /usr/include/gmp.h 34 | 35 | RUN wget http://launchpadlibrarian.net/140087283/libbison-dev_2.7.1.dfsg-1_amd64.deb 36 | RUN wget http://launchpadlibrarian.net/140087282/bison_2.7.1.dfsg-1_amd64.deb 37 | 38 | RUN dpkg -i libbison-dev_2.7.1.dfsg-1_amd64.deb 39 | RUN dpkg -i bison_2.7.1.dfsg-1_amd64.deb 40 | 41 | RUN ./buildconf --force 42 | 43 | RUN ./configure \ 44 | --prefix=$HOME/php7/usr \ 45 | --with-config-file-path=$HOME/php7/usr/etc \ 46 | --without-pear \ 47 | --enable-shared=no \ 48 | --enable-static=yes \ 49 | --enable-mbstring \ 50 | --enable-zip \ 51 | --enable-bcmath \ 52 | --enable-pcntl \ 53 | --enable-exif \ 54 | --enable-calendar \ 55 | --enable-sysvmsg \ 56 | --enable-sysvsem \ 57 | --enable-sysvshm \ 58 | --enable-json \ 59 | --with-curl \ 60 | --with-iconv \ 61 | --with-gmp \ 62 | --with-gd \ 63 | --enable-ctype \ 64 | --enable-pdo \ 65 | --with-mysqli=mysqlnd \ 66 | --with-pdo-mysql=mysqlnd \ 67 | --enable-gd-native-ttf \ 68 | --enable-gd-jis-conv \ 69 | --libdir=/usr/lib64 \ 70 | --disable-opcache \ 71 | --disable-cgi 72 | 73 | RUN make 74 | 75 | RUN make install 76 | 77 | RUN strip /root/php7/usr/bin/php 78 | -------------------------------------------------------------------------------- /Dockerfile.TestLambdaApp: -------------------------------------------------------------------------------- 1 | FROM node:argon 2 | 3 | # Create app directory 4 | RUN mkdir -p /usr/src/app 5 | WORKDIR /usr/src/app 6 | 7 | # Install app dependencies 8 | COPY package.json /usr/src/app/ 9 | RUN npm install 10 | 11 | # Bundle app source 12 | COPY . /usr/src/app 13 | 14 | CMD [ "npm", "test" ] -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Danny Linden 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Running PHP on AWS Lambda 2 | [![Build Status](https://travis-ci.org/dannylinden/aws-lambda-php.svg?branch=master)](https://travis-ci.org/dannylinden/aws-lambda-php) 3 | ## Prerequisite 4 | - [docker](https://www.docker.com/) 5 | 6 | ### Compile static standalone PHP 7 binary 7 | In order to use PHP on AWS Lambda, the PHP binary, including the required libraries, has to be integrated into the app. 8 | To do this, we have to compile the PHP 7.1.0RC5 with statically linked libraries: 9 | 10 | ```shell 11 | sh build_php_7.sh 12 | ``` 13 | 14 | ### PHP Version 15 | We are using PHP 7.1.0RC5 to compile the PHP binary 16 | To switch the PHP version you can set the Branch to checkout sources from a different branch 17 | by editing the "PHP_VERSION_GIT_BRANCH param on `sh build_php_7.sh` at line 8 18 | 19 | ### Running local Unittest for the PHP Example Application 20 | You can run the NodeJs Unittest with "lambda-tester" by building and running the specific docker container: 21 | 22 | ```shell 23 | docker build -t lambda-php-unittest -f Dockerfile.TestLambdaApp . 24 | ``` 25 | ```shell 26 | docker run lambda-php-unittest 27 | ``` 28 | 29 | ### Running Example Application on AWS 30 | To get the example application running on AWS you have to zip the php example script file, 31 | the NodeJS script file and the PHP binary together: 32 | 33 | ```shell 34 | zip aws-lambda-php-example.zip index.js index.php php 35 | ``` 36 | 37 | ### Create Example Lambda Function 38 | Now you can create a new Lambda function on AWS and upload the ZIP package: 39 | ![aws lambda php console settings](https://raw.githubusercontent.com/dannylinden/aws-lambda-php/master/img/aws-lambda.settings.png) 40 | -------------------------------------------------------------------------------- /build_php_7.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This Script build a docker container, compile PHP for use in AWS Lambda, 4 | # copy the final binary to the Host and remove the container 5 | # 6 | # You can specify the PHP Version by setting the Git Branch from https://github.com/php/php-src 7 | 8 | PHP_VERSION_GIT_BRANCH=PHP-7.2.6 9 | 10 | echo "Build PHP Binary from current branch '$PHP_VERSION_GIT_BRANCH' on https://github.com/php/php-src" 11 | 12 | docker build --build-arg PHP_VERSION=$PHP_VERSION_GIT_BRANCH -t php-build -f Dockerfile.BuildPHP . 13 | 14 | container=$(docker create php-build) 15 | 16 | docker -D cp $container:/root/php7/usr/bin/php ./php 17 | 18 | docker rm $container 19 | -------------------------------------------------------------------------------- /img/aws-lambda.settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dannylinden/aws-lambda-php/72d3000d77e1a182793d55eb93851333888e795a/img/aws-lambda.settings.png -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var child_process = require('child_process'); 4 | 5 | exports.handler = function(event, context) { 6 | 7 | var strToReturn = ''; 8 | 9 | var proc = child_process.spawn('./php', [ "index.php", JSON.stringify(event), { stdio: 'inherit' } ]); 10 | 11 | proc.stdout.on('data', function (data) { 12 | 13 | var dataStr = data.toString() 14 | console.log('stdout: ' + dataStr); 15 | strToReturn += dataStr 16 | 17 | }); 18 | 19 | proc.on('close', function(code) { 20 | if(code !== 0) { 21 | return context.done(new Error("Process exited with non-zero status code")); 22 | } 23 | 24 | context.succeed(strToReturn); 25 | }); 26 | } -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | (https://twitter.com/CodingDanny)", 13 | "license": "MIT", 14 | "devDependencies": { 15 | "chai": "^3.5.0", 16 | "mocha": "^2.4.5", 17 | "lambda-tester": "^2.0.0" 18 | }, 19 | "repository" : { 20 | "type" : "git", 21 | "url" : "https://github.com/dannylinden/aws-lambda-php" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /test/index.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const expect = require( 'chai' ).expect; 4 | 5 | const mainHandler = require( '../index' ).handler; 6 | 7 | const LambdaTester = require( 'lambda-tester' ); 8 | 9 | describe( 'index.js', function() { 10 | 11 | it( 'handler', function(done) { 12 | 13 | let event = { 14 | eventTestKey: 'eventTestValue' 15 | }; 16 | 17 | LambdaTester( mainHandler ) 18 | .event( event ) 19 | .expectSucceed( function( result ) { 20 | expect( result ).to.contain( 'string(33) "{"eventTestKey":"eventTestValue"}"' ); 21 | }).verify(done); 22 | }); 23 | }); --------------------------------------------------------------------------------