skip to Main Content

UPDATE: Thank you all! I have solved this by creating a custom runtime for my PHP Lambda.

I am currently using Node.js 8.10 Runtime with a php.handler and my Lambda function works fine, but when I change the Runtime to 12.x, I get the following error:

“php-7-bin/bin/php: error while loading shared libraries: libcrypt.so.1: cannot open shared object file: No such file or directory”

exports.handler = function(event, context, callback) {
    var php = spawn('php-7-bin/bin/php',['--php-ini', 'user.ini', process.env['PHPFILE']], {maxBuffer: 200 * 1024 * 200});
    var output = "";
    var statusCode = 0;

    php.stdin.write(JSON.stringify(event));

    php.stdin.end();

    php.stdout.on('data', function(data) {
          console.log("CHUNK: " + data);
          output+=data;
    });

    php.stderr.on('data', function(data) {
       console.log(data);
    });

      php.on('close', function(code) {
        var obj = JSON.parse(output);
        statusCode = obj.status.statusCode;
        if(statusCode !== 0){
          callback(output);
        }else{
          context.succeed(obj);
        }

      });
}

I need to update my Lambda to the latest node.js version, but I have no idea how to overcome this error, so any help would be greatly appreciated!

3

Answers


  1. First, why on earth are you using node to load php?

    But if you had this working before, why do you need to update to node 12?

    If you are upgrading from Node 8, the runtime is different:
    https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html

    So then take a look here:
    https://aws.amazon.com/blogs/apn/aws-lambda-custom-runtime-for-php-a-practical-example/

    You may need to create a new custom runtime based off the node12 built-in runtime for AWS.

    Login or Signup to reply.
  2. Easy fix is to add on top of your PHP code:

    set_include_path('/opt/lib64’);
    

    If that won’t work you need to compile/build/install the missing modules/libraries by yourself:

    • Run two docker instances that will have mounted the same “local” Layer folder.
    • First container is going to be your lambda container while second one is Amazon linux used to build items.
    • Test your code with Lambda container and in case something is missing switch to Amazon Linux and build/extract binaries/libraries into shared Layer folder structure.
    • Make sure the Lambda code have proper PATH defined to use Layer folder.

      1. Install docker.
      2. In first terminal tab go to your lambda folder and start the lambda docker container:
    docker run --rm -it --entrypoint=/bin/bash  -v  "$PWD":/var/task:ro,delegated -v /your/path/to/Layer/folder/:/opt:rw,delegated -e AWS_ACCESS_KEY_ID=[ACCESS_KEY_PASTE_HERE  -e AWS_SECRET_ACCESS_KEY=[SECRET_GOES_HERE] lambci/lambda:nodejs12.x
    
    1. In second terminal tab run another container with Amazon linux:
    docker run --rm -it -v /your/path/to/Layer/folder/:/opt:rw,delegated amazonlinux:latest
    

    (Keep in mind that the Layer folder is mounted with read/write permissions).

    1. Test your lambda code in your favourite way or just by simple run (make sure to check if your handler module name is “handler” and file name is “index.js”):
    
cd /var/task
node index.js; node "var func = require('./index.js');func.handler({},function() {},function(){console.log('Lambda finished')});"
    
    1. In case you find some missing libraries, make sure to add to your PHP code:

    set_include_path('/opt/lib');
    
    1. Then on Amazon Linux terminal tab and install/build your library and then copy it to Layer folder:
    cp /usr/lib64/[here is your library name] /opt/lib
    
    1. Test again your code in Lambda container.
    2. When you will be done just zip the content of your Lambda Layer structure, keep in mind that your bin ora lib folders need to be in the root folder of the zip file.
    3. Add the zip file as a Layer for you lambdas and attach it.
    Login or Signup to reply.
  3. I Fix this problem by adding extra library folder in my function’s zip.

    Make a directory name extra-libs

    Copy all required libraries from Amazon Linux 2 to Extra-libs by using following steps :

    1. Run amazon Linux 2’s docker instance by following command

      docker run --rm -it -v :/opt:rw,delegated amazonlinux:latest

    2. Then in docker instance make directory using

      mkdir deps

    3. Copy all required libraries from lib64 to deps directory using

      cp -f lib64/libcrypt.so.1 deps (Taken libcrypt.so.1 for example purpose)

    4. Then open another terminal window and move all library files to local extra-libs

      docker cp <DOCKER_CONTAINER_ID>:/deps/ . && mv deps/* ./extra-libs

      Get container id by using docker ps

    Then in index.js file , add following line to php’s env setting.

    LD_LIBRARY_PATH:path.join(__dirname, '/extra-libs')
    

    Zip extra-libs folder with your lambda function and upload it.

    Hope this helps.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search