-
-
Notifications
You must be signed in to change notification settings - Fork 93
Add FrankenPHP docs #412
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
Merged
Merged
Add FrankenPHP docs #412
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,220 @@ | ||
| # Using Yii with FrankenPHP | ||
|
|
||
| [FrankenPHP](https://frankenphp.dev/) is an application server for PHP with Caddy built in. It can run Yii in | ||
| [worker mode](using-with-event-loop.md), allowing the framework bootstrap to happen once per worker instead of | ||
| once per request. | ||
|
|
||
| ## Installation | ||
|
|
||
| Install the FrankenPHP runner package with Composer: | ||
|
|
||
| ```shell | ||
| composer require yiisoft/yii-runner-frankenphp | ||
| ``` | ||
|
|
||
| FrankenPHP works especially well in containerized deployments and is the runtime used by the Yii application | ||
| templates Docker setup described in [Docker in application templates](docker.md). | ||
|
|
||
| ## Configuration | ||
|
|
||
| First, configure the worker entry script. | ||
|
|
||
| ### Worker entry script | ||
|
|
||
| Create `/worker.php` in the project root: | ||
|
|
||
| ```php | ||
| <?php | ||
|
|
||
| declare(strict_types=1); | ||
|
|
||
| use App\Environment; | ||
| use Psr\Log\LogLevel; | ||
| use Yiisoft\ErrorHandler\ErrorHandler; | ||
| use Yiisoft\ErrorHandler\Renderer\PlainTextRenderer; | ||
| use Yiisoft\Log\Logger; | ||
| use Yiisoft\Log\StreamTarget; | ||
| use Yiisoft\Yii\Runner\FrankenPHP\FrankenPHPApplicationRunner; | ||
|
|
||
| $root = __DIR__; | ||
|
|
||
| require_once $root . '/src/bootstrap.php'; | ||
|
|
||
| if (Environment::appC3()) { | ||
| $c3 = $root . '/c3.php'; | ||
| if (file_exists($c3)) { | ||
| require_once $c3; | ||
| } | ||
| } | ||
|
|
||
| $runner = new FrankenPHPApplicationRunner( | ||
| rootPath: $root, | ||
| debug: Environment::appDebug(), | ||
| checkEvents: Environment::appDebug(), | ||
| environment: Environment::appEnv(), | ||
| temporaryErrorHandler: new ErrorHandler( | ||
| new Logger( | ||
| [ | ||
| (new StreamTarget())->setLevels([ | ||
| LogLevel::EMERGENCY, | ||
| LogLevel::ERROR, | ||
| LogLevel::WARNING, | ||
| ]), | ||
| ], | ||
| ), | ||
| new PlainTextRenderer(), | ||
| ), | ||
| ); | ||
| $runner->run(); | ||
| ``` | ||
|
|
||
| The runner bootstraps the application once and then keeps processing requests in worker mode. Unlike classic | ||
| `public/index.php`, this script is not executed per request. | ||
|
|
||
| ### Server configuration | ||
|
|
||
| FrankenPHP is configured through a `Caddyfile`. For production, it may look like the following: | ||
|
|
||
| ```caddyfile | ||
| { | ||
| skip_install_trust | ||
|
|
||
| frankenphp { | ||
|
|
||
| } | ||
| } | ||
|
|
||
| {$SERVER_NAME::80} { | ||
| encode zstd br gzip | ||
| php_server { | ||
| root /app/public | ||
| worker { | ||
| match * | ||
| file /app/worker.php | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| This configuration tells FrankenPHP to serve the `public` directory and handle all requests with `worker.php`. | ||
| Static assets are still served from `public`, while PHP requests are processed through the long-running worker. | ||
|
|
||
| For development, add `watch` so FrankenPHP reloads workers when PHP files change: | ||
|
|
||
| ```caddyfile | ||
| { | ||
| skip_install_trust | ||
|
|
||
| frankenphp { | ||
|
|
||
| } | ||
| } | ||
|
|
||
| {$SERVER_NAME::80} { | ||
| encode zstd br gzip | ||
| php_server { | ||
| root /app/public | ||
| worker { | ||
| match * | ||
| file /app/worker.php | ||
| watch /app/**/*.php | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ### Docker setup in Yii application templates | ||
|
|
||
| Yii application templates already ship with a FrankenPHP-based Docker setup. To switch the application to worker mode, | ||
| update the files inside the Docker layout instead of relying on `public/index.php`. | ||
|
|
||
| Create `/worker.php` in the project root as shown above, then update the Caddy configuration used by the container. | ||
| For development, edit `docker/dev/Caddyfile`: | ||
|
|
||
| ```caddyfile | ||
| { | ||
| skip_install_trust | ||
|
|
||
| frankenphp { | ||
|
|
||
| } | ||
| } | ||
|
|
||
| {$SERVER_NAME::80} { | ||
| encode zstd br gzip | ||
| php_server { | ||
| root /app/public | ||
| worker { | ||
| match * | ||
| file /app/worker.php | ||
| watch /app/**/*.php | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| For production, use the same configuration without `watch` in `docker/Caddyfile`: | ||
|
|
||
| ```caddyfile | ||
| { | ||
| skip_install_trust | ||
|
|
||
| frankenphp { | ||
|
|
||
| } | ||
| } | ||
|
|
||
| {$SERVER_NAME::80} { | ||
| encode zstd br gzip | ||
| php_server { | ||
| root /app/public | ||
| worker { | ||
| match * | ||
| file /app/worker.php | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| The templates use `dunglas/frankenphp` as the base image in `docker/Dockerfile`, mount the project into `/app` | ||
| in development, and pass runtime configuration through environment files such as `docker/dev/.env` and | ||
| `docker/prod/.env`. The default value of `SERVER_NAME` in these files is `:80`, which matches the examples above. | ||
|
|
||
| After changing `worker.php` and the relevant `Caddyfile`, rebuild the image and restart the environment: | ||
|
|
||
| ```shell | ||
| make build | ||
| make up | ||
| ``` | ||
|
|
||
| In production, rebuild and deploy the production image using the project's production Docker workflow. | ||
|
|
||
| If you switch fully to worker mode, `public/index.php` and `yiisoft/yii-runner-http` are no longer needed. | ||
|
|
||
| ## Starting a server | ||
|
|
||
| The exact start command depends on how you run FrankenPHP: | ||
|
|
||
| - In the Yii application templates, run `make build` and `make up` after updating `worker.php` and the relevant `Caddyfile`. | ||
| - In a custom setup, start FrankenPHP with the Caddy configuration that points to your application `Caddyfile`. | ||
|
|
||
| ## On worker scope | ||
|
|
||
| - Each worker's memory is isolated from other workers. | ||
| - A single worker handles multiple requests, so services created inside it may keep state between requests. | ||
| - At each iteration of the event loop, every stateful service should be reset. | ||
|
|
||
| For the general implications of long-running workers, see [Using Yii with event loop](using-with-event-loop.md). | ||
|
|
||
| ## Worker mode notes | ||
|
|
||
| - Use the `MAX_REQUESTS` environment variable to limit how many requests a worker handles before restart. | ||
| - Reset stateful services after each request. See [Yii DI `StateResetter` documentation](https://github.com/yiisoft/di#resetting-services-state). | ||
|
|
||
| ## Additional configuration | ||
|
|
||
| `FrankenPHPApplicationRunner` is configured by default for Yii application templates and follows the | ||
| [config groups convention](https://github.com/yiisoft/docs/blob/master/022-config-groups.md). | ||
|
|
||
| The constructor allows overriding the default bootstrap, events, DI, params, and error-handler configuration. | ||
| You can also provide a custom config instance with `withConfig()` and a custom container with `withContainer()`. | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The "config groups convention" link points to the GitHub repo (yiisoft/docs) even though this repository already contains the canonical document at
src/internals/022-config-groups.md. For consistency with other guide pages that link tosrc/internals/*via relative paths (e.g.,src/guide/intro/what-is-yii.md), update this to a relative link (e.g.,../../internals/022-config-groups.md) so it stays version-aligned with the published guide.