hammerstone/sidecar
Sidecar lets Laravel package, deploy, and invoke AWS Lambda functions directly from your app. Define a simple PHP class plus the files to ship, choose any supported runtime (Node, Python, Java, .NET, Ruby, or OS-only), and execute from PHP.
## Getting Started
### Minimal Setup
1. **Installation**
```bash
composer require hammerstone/sidecar
php artisan sidecar:configure
configure command to set up AWS credentials and region.Define a Lambda Function
Create a PHP class extending Hammerstone\Sidecar\LambdaFunction:
// app/Sidecar/ExampleFunction.php
namespace App\Sidecar;
use Hammerstone\Sidecar\LambdaFunction;
class ExampleFunction extends LambdaFunction
{
public function handler()
{
return 'handler.handler'; // Points to `resources/lambda/handler.js`
}
public function package()
{
return ['resources/lambda'];
}
}
Deploy
php artisan sidecar:deploy --activate
Execute
// In a route/controller
$result = ExampleFunction::execute(['key' => 'value']);
resources/lambda/image.js):
exports.handler = async (event) => {
return { image: `Generated for: ${event.text}` };
};
$response = OgImage::execute(['text' => 'Hello, Sidecar!']);
app/Sidecar/ for clarity.PdfGenerator, ImageProcessor).resources/lambda/ (e.g., pdf-generator.js, image-processor.py).Deploy:
php artisan sidecar:deploy --activate # Deploys and activates all functions
php artisan sidecar:deploy ExampleFunction # Deploy a single function
--pre-warm to initialize Lambda instances immediately.Execute:
// Sync execution (blocks until response)
$result = ExampleFunction::execute(['input' => 'data']);
// Async execution (returns a Promise)
$promise = ExampleFunction::executeAsync(['input' => 'data']);
$result = $promise->wait();
Monitor:
sidecar:logs:
php artisan sidecar:logs ExampleFunction
// app/Providers/AppServiceProvider.php
public function register()
{
$this->app->singleton(ExampleFunction::class);
}
use App\Sidecar\ExampleFunction;
use Illuminate\Bus\Queueable;
class ProcessData implements ShouldQueue
{
use Queueable;
public function handle()
{
$result = ExampleFunction::execute(['data' => $this->data]);
}
}
public function environment()
{
return [
'API_KEY' => env('AWS_API_KEY'),
'DEBUG' => app()->environment('local'),
];
}
process.env.API_KEY in Node.js).public function runtime()
{
return 'python3.12';
}
sidecar:deploy --env=testing to deploy to a separate environment.$mock = Mockery::mock(ExampleFunction::class);
$mock->shouldReceive('execute')->andReturn(['mocked' => 'response']);
Runtime Mismatches:
public function runtime() { return 'nodejs14.x'; }
.NET 7, Python 3.8) will fail silently. Use supported versions.File Path Issues:
/) or DIRECTORY_SEPARATOR:
return ['resources/lambda' . DIRECTORY_SEPARATOR . '*.js'];
resources/).Cold Starts:
--pre-warm during deploy or call sidecar:warm:
php artisan sidecar:warm ExampleFunction
Permission Errors:
php artisan sidecar:configure if you see AccessDenied errors.lambda:InvokeFunction permissions.Payload Size Limits:
public function execute($payload)
{
if (sizeof($payload) > 6_000_000) {
return $this->uploadToS3AndInvoke($payload);
}
return parent::execute($payload);
}
Environment Collisions:
APP_ENV for Sidecar. Use sidecar.env in .env:
SIDECAR_ENV=staging
Logs:
php artisan sidecar:logs ExampleFunction --tail
Error Handling:
try {
$result = ExampleFunction::execute($data);
} catch (\Hammerstone\Sidecar\Exceptions\LambdaException $e) {
report($e);
return response()->json(['error' => $e->getMessage()], 500);
}
SettledResult for async operations:
$result = ExampleFunction::executeAsync($data)->wait();
if ($result->isError()) {
throw new \Exception($result->errorAsString());
}
Deployment Issues:
.env:
AWS_ACCESS_KEY_ID=your_key
AWS_SECRET_ACCESS_KEY=your_secret
AWS_DEFAULT_REGION=us-east-1
aws lambda list-functions.Function Naming:
APP_NAME may cause issues. Use sidecar:configure to adjust naming conventions.Custom Deployment Logic:
deploy() in your function class:
public function deploy()
{
$this->package()->include('custom/path');
parent::deploy();
}
Package Macros:
Package class:
\Hammerstone\Sidecar\Support\Package::macro('includeNodeModules', function () {
return $this->include('node_modules');
});
Usage:
public function package()
{
return (new \Hammerstone\Sidecar\Support\Package)
->includeNodeModules()
->include('src');
}
Event-Driven Lambdas:
event() to trigger functions from S3, SQS, etc.:
public function event()
{
return 's3:ObjectCreated:*';
}
aws lambda add-permission.Container Images:
containerImageUri():
public function containerImageUri()
{
return '123456789012.dkr.ecr.us-east-1.amazonaws.com/my-repo:latest';
}
Memory/Timeout:
public function memory() { return 512; } // MB
public function timeout() { return 30; } // seconds
Ephemeral Storage:
public function ephemeralStorage() { return 1024; } // MB
Concurrency:
public function
How can I help you explore Laravel packages today?