Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better documentation around function runtime and Symfony in Docker #1840

Open
cameronmurphy opened this issue Jul 8, 2024 · 5 comments
Open

Comments

@cameronmurphy
Copy link

cameronmurphy commented Jul 8, 2024

There's no documentation on how to use the docker function runtime to run a Symfony console command. My lambda function is invoked by SES, and I need access to the database, so I had to boot the Kernel.

This was my solution
src/LambdaKernel.php:

<?php

namespace App;

class LambdaKernel extends Kernel
{
    public function getCacheDir(): string
    {
        return '/tmp/cache';
    }

    public function getLogDir(): string
    {
        return '/tmp/log';
    }
}

bin/lambda-handler.php:

<?php

require __DIR__ . '/../vendor/autoload.php';

use App\LambdaKernel;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\BufferedOutput;
use Symfony\Component\Dotenv\Dotenv;

(new Dotenv())->bootEnv(dirname(__DIR__) . '/.env');

$env = $_SERVER['APP_ENV'] ?? 'dev';
$debug = $_SERVER['APP_DEBUG'] ?? ('prod' !== $env);

$kernel = new LambdaKernel($env, $debug);
$application = new Application($kernel);

$application->setAutoExit(false);
$application->setCatchErrors(false);

return function (array $event) use ($application): array {
    $input = new ArrayInput([
        'command' => 'app:console-command-to-execute',
        'event' => json_encode($event),
    ]);
    $output = new BufferedOutput();

    $result = $application->run($input, $output);

    return [
        'success' => 0 === $result,
        'output' => $output->fetch(),
    ];
};

Dockerfile:

FROM bref/php-82:2

COPY . /var/task

CMD ["bin/lambda-handler.php"]

The real gotcha was preventing the application from auto exiting, which was putting the application into a loop and running the console command repeatedly.

Maybe it's just a really niche use case, but I was surprised by how difficult it was to deploy a single Symfony console command as a dockerised lambda function (where I don't have to invoke with specific arguments).

@mnapoli
Copy link
Member

mnapoli commented Jul 8, 2024

Why not use the console runtime? (https://bref.sh/docs/runtimes/console)

@cameronmurphy
Copy link
Author

I did try but because event is an array when data is coming in from SES, this line prevents event data from getting to my handler.

// Backward compatibility with the former CLI invocation format

@mnapoli
Copy link
Member

mnapoli commented Jul 8, 2024

Oh sorry I misread that. I think you want to use this feature instead of rebuilding it from scratch: https://github.com/brefphp/symfony-bridge?tab=readme-ov-file#class-handlers

@cameronmurphy
Copy link
Author

cameronmurphy commented Jul 8, 2024

I looked at this but I couldn't figure out how to invoke that class handler inside my Docker container locally? Only invoking plain PHP file handlers is documented.

https://bref.sh/docs/local-development/event-driven-functions#with-docker

Also which handler class would I use for SES events?

@mnapoli
Copy link
Member

mnapoli commented Jul 9, 2024

Try something like this:

docker run --rm -it -v $(PWD):/var/task:ro bref/php-81-fpm-dev:2 vendor/bin/bref-local "My\\Class"

(I think you need to escape the backslashes)

For SES there is no specific handler class. You can implement the Bref\Event\Handler interface.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants