Skip to content

Commit 14d86c3

Browse files
authored
Document Rapira and improve FrankenPHP setup (#532)
1 parent ed9723d commit 14d86c3

6 files changed

Lines changed: 151 additions & 6 deletions

File tree

‎src/.vitepress/config.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ export default {
174174
{text: 'Performance Tuning', link: '/guide/tutorial/performance-tuning'},
175175
{text: 'Using with Event Loop', link: '/guide/tutorial/using-with-event-loop'},
176176
{text: 'Using Yii with FrankenPHP', link: '/guide/tutorial/using-yii-with-frankenphp'},
177+
{text: 'Using Yii with Rapira', link: '/guide/tutorial/using-yii-with-rapira'},
177178
{text: 'Using Yii with RoadRunner', link: '/guide/tutorial/using-yii-with-roadrunner'},
178179
{text: 'Using Yii with Swoole', link: '/guide/tutorial/using-yii-with-swoole'},
179180
{text: 'Docker in Application Templates', link: '/guide/tutorial/docker'},

‎src/guide/index.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ We release this guide under the [Terms of Yii Documentation](https://www.yiifram
138138
- [Performance tuning](tutorial/performance-tuning.md)
139139
- [Using Yii with event loop](tutorial/using-with-event-loop.md)
140140
- [Using Yii with FrankenPHP](tutorial/using-yii-with-frankenphp.md)
141+
- [Using Yii with Rapira](tutorial/using-yii-with-rapira.md)
141142
- [Using Yii with RoadRunner](tutorial/using-yii-with-roadrunner.md)
142143
- [Using Yii with Swoole](tutorial/using-yii-with-swoole.md)
143144
- [Docker in application templates](tutorial/docker.md)

‎src/guide/structure/entry-script.md‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,9 @@ try {
101101

102102
## Alternative runtimes
103103

104-
For alternative runtimes such as FrankenPHP, RoadRunner, or Swoole, special entry scripts should be used. See:
104+
For alternative runtimes such as FrankenPHP, Rapira, RoadRunner, or Swoole, special entry scripts should be used. See:
105105

106106
- [Using Yii with FrankenPHP](../tutorial/using-yii-with-frankenphp.md)
107+
- [Using Yii with Rapira](../tutorial/using-yii-with-rapira.md)
107108
- [Using Yii with RoadRunner](../tutorial/using-yii-with-roadrunner.md)
108109
- [Using Yii with Swoole](../tutorial/using-yii-with-swoole.md)

‎src/guide/tutorial/using-with-event-loop.md‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ There is an alternative way of running an application. Event loop. The idea is t
1010
and then process a number of requests using it. Such an approach is usually called event loop.
1111

1212
There are multiple tools that could be used to achieve it. Notably, [FrankenPHP](https://frankenphp.dev/),
13-
[RoadRunner](https://roadrunner.dev/) and [Swoole](https://www.swoole.com/).
13+
[Rapira](https://rapira.rs/), [RoadRunner](https://roadrunner.dev/) and [Swoole](https://www.swoole.com/).
1414

1515
## Event loop implications
1616

@@ -56,5 +56,6 @@ while ($request = getRequest()) {
5656
## Integrations
5757

5858
- [FrankenPHP](using-yii-with-frankenphp.md)
59+
- [Rapira](using-yii-with-rapira.md)
5960
- [RoadRunner](using-yii-with-roadrunner.md)
6061
- [Swoole](using-yii-with-swoole.md)

‎src/guide/tutorial/using-yii-with-frankenphp.md‎

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@ once per request.
66

77
## Installation
88

9-
Install the FrankenPHP runner package with Composer:
9+
The [FrankenPHP runner](https://github.com/yiisoft/yii-runner-frankenphp) requires PHP 8.1–8.5.
10+
Install FrankenPHP using its [installation instructions](https://frankenphp.dev/docs/), or use the Docker setup
11+
in the Yii application templates described below.
12+
13+
Install the runner package with Composer:
1014

1115
```shell
1216
composer require yiisoft/yii-runner-frankenphp
@@ -15,6 +19,10 @@ composer require yiisoft/yii-runner-frankenphp
1519
FrankenPHP works especially well in containerized deployments and is the runtime used by the Yii application
1620
templates Docker setup described in [Docker in application templates](docker.md).
1721

22+
> [!NOTE]
23+
> This runner is for worker mode. To use FrankenPHP in classic mode, keep `public/index.php` and
24+
> [yiisoft/yii-runner-http](https://github.com/yiisoft/yii-runner-http), the default HTTP runner in the templates.
25+
1826
## Configuration
1927

2028
First, configure the worker entry script.
@@ -196,7 +204,15 @@ If you switch fully to worker mode, `public/index.php` and `yiisoft/yii-runner-h
196204
The exact start command depends on how you run FrankenPHP:
197205

198206
- In the Yii application templates, run `make build` and `make up` after updating `worker.php` and the relevant `Caddyfile`.
199-
- In a custom setup, start FrankenPHP with the Caddy configuration that points to your application `Caddyfile`.
207+
- With the standalone binary, run the following command from the directory containing your `Caddyfile`:
208+
209+
```shell
210+
frankenphp run --config Caddyfile
211+
```
212+
213+
The example configuration uses `/app` as the application root. Adjust `/app/public`, `/app/worker.php`, and the
214+
watch path to match your installation. See the [FrankenPHP configuration reference](https://frankenphp.dev/docs/config/)
215+
for other deployment options.
200216

201217
## On worker scope
202218

@@ -209,12 +225,13 @@ For the general implications of long-running workers, see [Using Yii with event
209225
## Worker mode notes
210226

211227
- Use the `MAX_REQUESTS` environment variable to limit how many requests a worker handles before restart.
212-
- Reset stateful services after each request. See [Yii DI `StateResetter` documentation](https://github.com/yiisoft/di#resetting-services-state).
228+
- The runner calls `Yiisoft\Di\StateResetter::reset()` after each request. Register resetters for your stateful
229+
services as described in the [Yii DI documentation](https://github.com/yiisoft/di#resetting-services-state).
213230

214231
## Additional configuration
215232

216233
`FrankenPHPApplicationRunner` is configured by default for Yii application templates and follows the
217-
[dependency container configuration](../../guide/concept/configuration.html#container-configuration) concept.
234+
[dependency container configuration](../concept/configuration.md#container-configuration) concept.
218235

219236
The constructor allows overriding the default bootstrap, events, DI, params, and error-handler configuration.
220237
You can also provide a custom config instance with `withConfig()` and a custom container with `withContainer()`.
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
# Using Yii with Rapira
2+
3+
[Rapira](https://rapira.rs/) is a PHP application server written in Rust that embeds the PHP interpreter.
4+
The [Yii Rapira runner](https://github.com/yiisoft/yii-runner-rapira) supports its classic, worker, and dispatcher modes.
5+
Worker and dispatcher modes initialize the application once per worker and reuse it for subsequent requests.
6+
See [Using Yii with event loop](using-with-event-loop.md) for the implications of keeping the application in memory.
7+
8+
## Installation
9+
10+
The runner requires PHP 8.4–8.5. Install the Rapira binary following the
11+
[Rapira installation instructions](https://rapira.rs/docs/intro/installation), using a PHP version supported by the runner.
12+
The Composer packages provide the Yii integration; the server binary must be installed separately.
13+
14+
Install the runner and its contract package in your Yii application:
15+
16+
```shell
17+
composer require yiisoft/yii-runner-rapira:@dev rapira/contract:@dev
18+
```
19+
20+
These stability flags allow the development versions used by the runner's installation instructions.
21+
22+
## Configuration
23+
24+
The following example assumes an application based on `yiisoft/app` or `yiisoft/app-api`, with `App\Environment`
25+
and `src/bootstrap.php` provided by the template.
26+
27+
### Worker entry script
28+
29+
Create `worker.php` in the application root:
30+
31+
```php
32+
<?php
33+
34+
declare(strict_types=1);
35+
36+
use App\Environment;
37+
use Psr\Log\LogLevel;
38+
use Yiisoft\ErrorHandler\ErrorHandler;
39+
use Yiisoft\ErrorHandler\Renderer\PlainTextRenderer;
40+
use Yiisoft\Log\Logger;
41+
use Yiisoft\Log\StreamTarget;
42+
use Yiisoft\Yii\Runner\Rapira\RapiraApplicationRunner;
43+
44+
$root = __DIR__;
45+
46+
require_once $root . '/src/bootstrap.php';
47+
48+
$runner = new RapiraApplicationRunner(
49+
rootPath: $root,
50+
debug: Environment::appDebug(),
51+
checkEvents: Environment::appDebug(),
52+
environment: Environment::appEnv(),
53+
temporaryErrorHandler: new ErrorHandler(
54+
new Logger(
55+
[
56+
(new StreamTarget())->setLevels([
57+
LogLevel::EMERGENCY,
58+
LogLevel::ERROR,
59+
LogLevel::WARNING,
60+
]),
61+
],
62+
),
63+
new PlainTextRenderer(),
64+
),
65+
);
66+
$runner->run();
67+
```
68+
69+
The runner creates the container, starts the application, converts incoming requests to PSR-7 requests, and emits
70+
responses. It detects the Rapira execution mode, so the same entry script can be used with all three modes.
71+
72+
### Server configuration
73+
74+
Create `rapira.toml` next to `worker.php`:
75+
76+
```toml
77+
[http]
78+
listen = "127.0.0.1:8000"
79+
80+
[pool]
81+
entrypoint = "worker.php"
82+
mode = "worker"
83+
max_requests = 1000
84+
```
85+
86+
This configuration listens on the loopback interface and recycles each worker after 1,000 requests.
87+
For serving files from `public`, follow Rapira's [static file configuration](https://rapira.rs/docs/static-files).
88+
See the [configuration reference](https://rapira.rs/docs/configuration) for the other server and pool settings.
89+
90+
## Starting a server
91+
92+
Run the following command from the application root:
93+
94+
```shell
95+
rapira serve
96+
```
97+
98+
Open `http://127.0.0.1:8000` to access the application. Restart the server after changing application code or configuration.
99+
100+
## Execution modes
101+
102+
Set `mode` in the `[pool]` section of `rapira.toml` to choose how requests are processed:
103+
104+
- `classic` initializes the application for each request, similarly to PHP-FPM.
105+
- `worker` keeps the application in memory and receives requests through PHP's SAPI superglobals.
106+
- `dispatcher` keeps the application in memory and receives request objects through Rapira's dispatcher API.
107+
The Yii runner processes these requests sequentially within each worker.
108+
109+
See [Rapira execution modes](https://rapira.rs/docs/execution-modes) for details.
110+
111+
## On worker scope
112+
113+
In worker and dispatcher modes, services may retain state between requests. The runner calls
114+
`Yiisoft\Di\StateResetter::reset()` after each request, but you must configure resetters for your own stateful services.
115+
See the [Yii DI documentation](https://github.com/yiisoft/di#resetting-services-state).
116+
117+
The `max_requests` setting limits how long a worker lives; it does not replace resetting request-specific state.
118+
119+
## Additional configuration
120+
121+
`RapiraApplicationRunner` uses the application templates' web configuration groups by default. Its constructor accepts
122+
alternative groups, configuration directories, and a temporary error handler. Use `withConfig()` to supply a custom
123+
configuration instance or `withContainer()` to supply a PSR-11 container. See the
124+
[runner documentation](https://github.com/yiisoft/yii-runner-rapira#configuration) for examples.

0 commit comments

Comments
 (0)