Install the Package
composer require runtime/frankenphp-symfony
Ensure your composer.json includes the package under require.
Configure Environment
Set APP_RUNTIME to Runtime\FrankenPhpSymfony\Runtime in your .env or deployment environment:
APP_RUNTIME=Runtime\FrankenPhpSymfony\Runtime
Docker Deployment (Example) Use the provided Docker snippet, adjusting paths and ports as needed:
docker run \
-e FRANKENPHP_CONFIG="worker ./public/index.php" \
-e APP_RUNTIME=Runtime\FrankenPhpSymfony\Runtime \
-v $(pwd):/app \
-p 80:80 -p 443:443 \
dunglas/frankenphp
Kernel Bootstrapping
Update public/index.php to use the Symfony Runtime autoloader:
require_once dirname(__DIR__) . '/vendor/autoload_runtime.php';
return function (array $context) {
return new Kernel($context['APP_ENV'] ?? 'dev', (bool) ($context['APP_DEBUG'] ?? false));
};
Verify Runtime
Check logs (docker logs <container>) for confirmation of FrankenPHP-Symfony initialization.
APP_RUNTIME in .env.local for local testing.FRANKENPHP_CONFIG="worker ./public/index.php" to validate FrankenPHP integration.docker exec -it <container> sh if issues arise.Runtime Configuration
FRANKENPHP_CONFIG to define worker behavior (e.g., worker ./public/index.php).frankenphp_loop_max (default: 500) to manage worker restarts:
FRANKENPHP_CONFIG="worker ./public/index.php --loop-max 1000"
Dependency Injection
ContainerBuilder or Kernel logic remains unchanged.Context for environment-aware configurations (e.g., APP_ENV, APP_DEBUG).Hybrid Request Handling
HttpKernel for routing, controllers, and middleware as usual.Static Asset Serving
FRANKENPHP_CONFIG="static ./public --index index.php"
Event-Driven Extensions
Kernel::TERMINATE) to interact with FrankenPHP’s lifecycle:
// config/services.yaml
App\EventListener\FrankenPhpListener:
tags:
- { name: kernel.event_listener, event: kernel.terminate, method: onTerminate }
APP_RUNTIME in pipelines before deployment.docker run ... | tee frankenphp.log
frankenphp_loop_max to balance memory leaks and restarts.Environment Variable Order
APP_RUNTIME must be set before Symfony’s DotenvComponent loads (e.g., via Docker -e or .env)..env is loaded last or use explicit APP_RUNTIME in docker run.Worker Restarts
frankenphp_loop_max: -1 disables restarts, risking memory leaks in long-running apps.500 and adjust based on memory profiles.Static File Caching
Cache-Control:
// src/EventListener/AddCacheHeadersListener.php
public function onKernelRequest(RequestEvent $event) {
$request = $event->getRequest();
if ($request->isMethod('GET') && $request->getPathInfo() === '/static/file.jpg') {
$response = $event->getResponse();
$response->headers->set('Cache-Control', 'public, max-age=31536000');
}
}
Symfony Runtime Conflicts
Runtime\Symfony\Runtime and Runtime\FrankenPhpSymfony\Runtime in the same app.PHP Version Mismatch
Logs
docker logs --follow <container> | grep -i "frankenphp\|symfony"
APP_DEBUG=1) for stack traces.Worker Isolation
ErrorListener.try-catch in public/index.php for graceful failures:
return function (array $context) {
try {
return new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
} catch (\Throwable $e) {
file_put_contents('/tmp/runtime_error.log', $e->getMessage());
throw $e;
}
};
Configuration Validation
FRANKENPHP_CONFIG syntax. Example:
FRANKENPHP_CONFIG="worker ./public/index.php --loop-max 500 --static ./public"
--static may cause 404s for assets.Custom Runtime Classes
Runtime\FrankenPhpSymfony\Runtime to add pre/post-request hooks:
class CustomRuntime extends Runtime\FrankenPhpSymfony\Runtime {
public function __construct() {
parent::__construct();
$this->on('request', [$this, 'logRequest']);
}
public function logRequest(ServerRequestInterface $request) {
file_put_contents(
'/tmp/requests.log',
$request->getUri() . "\n",
FILE_APPEND
);
}
}
APP_RUNTIME=App\CustomRuntime.FrankenPHP CLI Commands
FRANKENPHP_CONFIG to enable CLI tools (e.g., cli ./bin/console):
FRANKENPHP_CONFIG="cli ./bin/console"
ConsoleApplication for unified CLI/runtime.Dynamic Configuration
getContext() in a custom runtime to inject dynamic values:
public function getContext(): array {
$context = parent::getContext();
$context['CUSTOM_VAR'] = 'dynamic_value';
return $context;
}
How can I help you explore Laravel packages today?