Skip to content

PHP Lambda "Runtime.ExitError"

0

Hi there!

I am deploying Docker Lambda function based on PHP 8.3 container:

FROM php:8.3-cli-alpine3.21

WORKDIR /var/task
COPY test.php test.php

CMD ["php", "test.php"]

Inside this container I am running following PHP script which at the end returns 0:

<?php

echo "test";

return 0;

And finally I am invoking the PHP function through EventBridge Rule like this:

    const handler = new DockerImageFunction(this, `PhpTest`, {
      code: DockerImageCode.fromImageAsset(`.`),
      architecture: Architecture.ARM_64
    });

    new Rule(this, `TestCronjob`, {
      enabled: this.enableCronJobs,
      schedule: Schedule.rate(Duration.minutes(1)),
      targets: [new LambdaFunction(handler)]
    });

In fact my real scenario is a bit more complicated - I am installing multiple PHP extensions and I am running Symfony command through bin/console inside the container - but this example should suffice.

Whenever I run the lambda I get following logs in CloudWatch:

test
INIT_REPORT Init Duration: 186.76 ms	Phase: init	Status: error	Error Type: Runtime.ExitError
test
INIT_REPORT Init Duration: 117.31 ms	Phase: invoke	Status: error	Error Type: Runtime.ExitError
START RequestId: e752e724-fc6b-4833-bf81-a44a7362e6b4 Version: $LATEST
RequestId: e752e724-fc6b-4833-bf81-a44a7362e6b4 Error: Runtime exited without providing a reason
Runtime.ExitError
END RequestId: e752e724-fc6b-4833-bf81-a44a7362e6b4
REPORT RequestId: e752e724-fc6b-4833-bf81-a44a7362e6b4	Duration: 270.49 ms	Billed Duration: 271 ms	Memory Size: 128 MB	Max Memory Used: 7 MB

So to me it seems that the code is executed twice within the init phase and then it exits without providing a reason.

I've seen that there are different runtimes for PHP like Bref.sh (cannot be used with my exapmle because I need PHP 8.3) etc. and I understand that I need to handle some states explained here https://docs.aws.amazon.com/lambda/latest/dg/runtimes-walkthrough.html but I thought that that's just for the API Gateway requests etc.

What is the easiest way to fix this? I wen't through the tutorial etc but I don't think I fully understand it.

asked 2 years ago108 views

1 Answer
0

The issue you're experiencing is likely due to how AWS Lambda expects container images to be structured and how it handles the execution of functions. When using a custom runtime or container image with Lambda, there are specific requirements that need to be met.

  1. Entry Point: Your Dockerfile is using CMD to specify the entry point, but Lambda expects an ENTRYPOINT instruction instead. The ENTRYPOINT should point to the Lambda runtime interface client, which handles the communication between Lambda and your function code.

  2. Handler Function: Lambda expects a handler function that it can invoke, rather than directly executing a script. Your current setup is running the PHP script directly, which doesn't align with how Lambda typically operates.

To fix this, you'll need to make a few changes:

  1. Modify your Dockerfile to include the Lambda runtime interface client and set it as the ENTRYPOINT.
  2. Create a PHP handler function that Lambda can invoke.
  3. Use CMD in your Dockerfile to specify the handler function.

Here's an example of how you might modify your Dockerfile:

FROM php:8.3-cli-alpine3.21

# Install the Lambda Runtime Interface Client
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
RUN composer require bref/bref

WORKDIR /var/task
COPY . .

# Set the Lambda Runtime Interface Client as the ENTRYPOINT
ENTRYPOINT ["/opt/bref/runtime/php/bootstrap"]

# Specify your handler function
CMD ["index.php"]

Then, create an index.php file with a handler function:

<?php

function handler($event, $context) {
    echo "test";
    return ['statusCode' => 200, 'body' => 'Hello from PHP Lambda!'];
}

This setup should resolve the Runtime.ExitError you're experiencing and allow your PHP function to run properly in Lambda. Remember to adjust your Lambda function configuration to point to the correct handler (e.g., "index.handler").

For more complex scenarios, like running Symfony commands, you may need to adapt this approach further, possibly by creating a custom runtime that can execute your Symfony commands within the Lambda environment.
Sources
AWS Lambda: Runtime.InvalidEntrypoint | AWS re:Post
Lambda Function built using Docker Image cannot find the lambda handler function | AWS re:Post

answered 2 years ago

  • I've also found this article which is great but does not solve my problem (nor do your answer unfortunatelly) - https://aws.amazon.com/blogs/apn/aws-lambda-custom-runtime-for-php-a-practical-example/

    Can you collaborate on how would I use this approach (either one - bref or custom runtime form my example) to run commands in Symfony console?

    https://symfony.com/doc/current/components/console.html

    My console file looks something like this:

    #!/usr/bin/env php
    <?php
    
    // if you don't want to setup permissions the proper way, just uncomment the following PHP line
    // read http://symfony.com/doc/current/book/installation.html#configuration-and-setup for more information
    umask(0000);
    
    set_time_limit(0);
    
    require __DIR__.'/../app/autoload.php';
    
    use Symfony\Bundle\FrameworkBundle\Console\Application;
    use Symfony\Component\Console\Input\ArgvInput;
    use Symfony\Component\ErrorHandler\Debug;
    
    $input = new ArgvInput();
    $env = $input->getParameterOption(array('--env', '-e'), getenv('SYMFONY_ENV') ?: 'dev');
    $debug = getenv('SYMFONY_DEBUG') !== '0' && !$input->hasParameterOption(array('--no-debug', '')) && $env !== 'prod';
    
    if ($debug) {
        Debug::enable();
    }
    
    $kernel = new AppKernel($env, $debug);
    $application = new Application($kernel);
    $application->run($input);
    

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.