From edd0d850479cf3a37f062a596ae59ecb386a905a Mon Sep 17 00:00:00 2001 From: brendt Date: Fri, 3 Oct 2025 11:07:49 +0200 Subject: [PATCH 1/4] wip --- Dockerfile | 12 ++++ packages/router/src/Commands/ServeCommand.php | 48 ++++++++++++-- packages/router/src/WorkerApplication.php | 66 +++++++++++++++++++ 3 files changed, 122 insertions(+), 4 deletions(-) create mode 100644 Dockerfile create mode 100644 packages/router/src/WorkerApplication.php diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..819cda117 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,12 @@ +FROM dunglas/frankenphp + +COPY . /app/public + +RUN install-php-extensions \ + pdo_mysql \ + gd \ + intl \ + zip \ + opcache + +ENV FRANKENPHP_CONFIG="worker ./public/index.php" diff --git a/packages/router/src/Commands/ServeCommand.php b/packages/router/src/Commands/ServeCommand.php index 192d0baef..63880d8d1 100644 --- a/packages/router/src/Commands/ServeCommand.php +++ b/packages/router/src/Commands/ServeCommand.php @@ -5,19 +5,26 @@ namespace Tempest\Router\Commands; use Tempest\Console\ConsoleCommand; +use Tempest\Console\HasConsole; use Tempest\Intl\Number; use Tempest\Support\Str; +use function Tempest\Support\path; final readonly class ServeCommand { + use HasConsole; + #[ConsoleCommand( name: 'serve', description: 'Starts a PHP development server', )] - public function __invoke(string $host = '127.0.0.1', int $port = 8000, string $publicDir = 'public/'): void - { - $routerFile = __DIR__ . '/router.php'; - + public function __invoke( + string $host = 'localhost', + int $port = 8000, + int $httpsPort = 4433, + string $publicDir = './public/', + bool $worker = false, + ): void { if (Str\contains($host, ':')) { [$host, $overriddenPort] = explode(':', $host, limit: 2); @@ -26,6 +33,39 @@ public function __invoke(string $host = '127.0.0.1', int $port = 8000, string $p $port = Number\parse($overriddenPort, default: $port); } + if ($worker) { + $this->worker($host, $port, $httpsPort, $publicDir); + } else { + $this->serve($host, $port, $publicDir); + } + } + + private function worker(string $host, int $port, int $httpsPort, string $publicDir): void + { + $this->success('Listening on http://' . $host . ':' . $port . ', https://' . $host . ':' . $httpsPort); + + $command = sprintf(<<<'SH' + docker run \ + -e FRANKENPHP_CONFIG="worker %s" \ + -v $PWD:/app \ + -p %d:80 -p %d:443 -p %d:443/udp \ + dunglas/frankenphp + SH, + path($publicDir, 'index.php')->toString(), + $port, + $httpsPort, + $httpsPort + ); + + $this->info($command); + + passthru($command); + } + + private function serve(string $host, int $port, string $publicDir): void + { + $routerFile = __DIR__ . '/router.php'; + passthru("php -S {$host}:{$port} -t {$publicDir} {$routerFile}"); } } diff --git a/packages/router/src/WorkerApplication.php b/packages/router/src/WorkerApplication.php new file mode 100644 index 000000000..1b00e43ad --- /dev/null +++ b/packages/router/src/WorkerApplication.php @@ -0,0 +1,66 @@ +get(WorkerApplication::class); + + // Application-specific setup + $logConfig = $container->get(LogConfig::class); + + if ($logConfig->debugLogPath === null && $logConfig->serverLogPath === null && $logConfig->channels === []) { + $logConfig->debugLogPath = path($container->get(Kernel::class)->root, '/log/debug.log')->toString(); + $logConfig->serverLogPath = env('SERVER_LOG'); + $logConfig->channels[] = new AppendLogChannel(path($root, '/log/tempest.log')->toString()); + } + + return $application; + } + + public function run(): void + { + $router = $this->container->get(Router::class); + + $psrRequest = $this->container->get(RequestFactory::class)->make(); + + $responseSender = $this->container->get(ResponseSender::class); + + $responseSender->send( + $router->dispatch($psrRequest), + ); + + $this->container->get(Session::class)->cleanup(); + + $this->container->invoke(FinishDeferredTasks::class); + } +} From 9e0cffc4e407fb8a8cb9ac15d164a5475617b1b3 Mon Sep 17 00:00:00 2001 From: brendt Date: Fri, 3 Oct 2025 11:29:40 +0200 Subject: [PATCH 2/4] wip --- Dockerfile | 4 ++-- public/index.php | 34 ++++++++++++++++++++++++++++------ 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/Dockerfile b/Dockerfile index 819cda117..c88830871 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,5 @@ FROM dunglas/frankenphp -COPY . /app/public - RUN install-php-extensions \ pdo_mysql \ gd \ @@ -9,4 +7,6 @@ RUN install-php-extensions \ zip \ opcache +COPY . /app + ENV FRANKENPHP_CONFIG="worker ./public/index.php" diff --git a/public/index.php b/public/index.php index 29a2f351f..431eae5af 100644 --- a/public/index.php +++ b/public/index.php @@ -1,14 +1,36 @@ run(); +if (function_exists('frankenphp_handle_request')) { + ignore_user_abort(true); + + $application = WorkerApplication::boot(__DIR__ . '/../'); + + $handler = static function () { +// $application->run(); + echo 'hi'; + }; + + $maxRequests = (int)($_SERVER['MAX_REQUESTS'] ?? 0); + + for ($nbRequests = 0; ! $maxRequests || $nbRequests < $maxRequests; ++$nbRequests) { + $keepRunning = frankenphp_handle_request($handler); + + gc_collect_cycles(); + + if (! $keepRunning) break; + } +} else { + HttpApplication::boot(__DIR__ . '/../', discoveryLocations: [ + new DiscoveryLocation('Tests\\Tempest\\Fixtures\\', __DIR__ . '/../tests/Fixtures/'), + ])->run(); + + exit(); + +} -exit(); From 8563867c0dff094acacde6ba19da7d5246e1d81a Mon Sep 17 00:00:00 2001 From: brendt Date: Sun, 5 Oct 2025 08:07:17 +0200 Subject: [PATCH 3/4] wip --- Dockerfile | 14 +++++--------- packages/router/src/Commands/ServeCommand.php | 2 +- public/index.php | 5 ++--- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/Dockerfile b/Dockerfile index c88830871..b69d5a5b0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,12 +1,8 @@ FROM dunglas/frankenphp RUN install-php-extensions \ - pdo_mysql \ - gd \ - intl \ - zip \ - opcache - -COPY . /app - -ENV FRANKENPHP_CONFIG="worker ./public/index.php" + pdo_mysql \ + gd \ + intl \ + zip \ + opcache diff --git a/packages/router/src/Commands/ServeCommand.php b/packages/router/src/Commands/ServeCommand.php index 63880d8d1..e1fd86355 100644 --- a/packages/router/src/Commands/ServeCommand.php +++ b/packages/router/src/Commands/ServeCommand.php @@ -49,7 +49,7 @@ private function worker(string $host, int $port, int $httpsPort, string $publicD -e FRANKENPHP_CONFIG="worker %s" \ -v $PWD:/app \ -p %d:80 -p %d:443 -p %d:443/udp \ - dunglas/frankenphp + tempest SH, path($publicDir, 'index.php')->toString(), $port, diff --git a/public/index.php b/public/index.php index 431eae5af..c6496c7d1 100644 --- a/public/index.php +++ b/public/index.php @@ -11,9 +11,8 @@ $application = WorkerApplication::boot(__DIR__ . '/../'); - $handler = static function () { -// $application->run(); - echo 'hi'; + $handler = static function () use ($application) { + $application->run(); }; $maxRequests = (int)($_SERVER['MAX_REQUESTS'] ?? 0); From c6ad8e4c911892e6dc471c87ec9d177c17f015f1 Mon Sep 17 00:00:00 2001 From: brendt Date: Sun, 5 Oct 2025 08:39:16 +0200 Subject: [PATCH 4/4] wip --- Caddyfile | 8 ++++++++ packages/router/src/Commands/ServeCommand.php | 4 ++-- public/index.php | 10 ++++++---- 3 files changed, 16 insertions(+), 6 deletions(-) create mode 100644 Caddyfile diff --git a/Caddyfile b/Caddyfile new file mode 100644 index 000000000..58a423ea3 --- /dev/null +++ b/Caddyfile @@ -0,0 +1,8 @@ +{ + frankenphp { + worker { + file /app/public/index.php + watch + } + } +} \ No newline at end of file diff --git a/packages/router/src/Commands/ServeCommand.php b/packages/router/src/Commands/ServeCommand.php index e1fd86355..6891b6ec7 100644 --- a/packages/router/src/Commands/ServeCommand.php +++ b/packages/router/src/Commands/ServeCommand.php @@ -42,8 +42,6 @@ public function __invoke( private function worker(string $host, int $port, int $httpsPort, string $publicDir): void { - $this->success('Listening on http://' . $host . ':' . $port . ', https://' . $host . ':' . $httpsPort); - $command = sprintf(<<<'SH' docker run \ -e FRANKENPHP_CONFIG="worker %s" \ @@ -57,6 +55,8 @@ private function worker(string $host, int $port, int $httpsPort, string $publicD $httpsPort ); + $this->info('Listening on http://' . $host . ':' . $port . ', https://' . $host . ':' . $httpsPort); + $this->info($command); passthru($command); diff --git a/public/index.php b/public/index.php index c6496c7d1..8aecfffd8 100644 --- a/public/index.php +++ b/public/index.php @@ -6,10 +6,14 @@ require_once __DIR__ . '/../vendor/autoload.php'; +$discoveryLocations = [ + new DiscoveryLocation('Tests\\Tempest\\Fixtures\\', __DIR__ . '/../tests/Fixtures/'), +]; + if (function_exists('frankenphp_handle_request')) { ignore_user_abort(true); - $application = WorkerApplication::boot(__DIR__ . '/../'); + $application = WorkerApplication::boot(__DIR__ . '/../', discoveryLocations: $discoveryLocations); $handler = static function () use ($application) { $application->run(); @@ -25,9 +29,7 @@ if (! $keepRunning) break; } } else { - HttpApplication::boot(__DIR__ . '/../', discoveryLocations: [ - new DiscoveryLocation('Tests\\Tempest\\Fixtures\\', __DIR__ . '/../tests/Fixtures/'), - ])->run(); + HttpApplication::boot(__DIR__ . '/../', discoveryLocations: $discoveryLocations)->run(); exit();