Laravel
Rapira запускает Laravel в классическом режиме: штатный фронт-контроллер public/index.php выполняется с нуля на каждый запрос, ровно так же, как его выполняет php-fpm. Менять в приложении ничего не нужно. Режим воркера для Laravel находится в разработке — о его текущем состоянии рассказывает раздел Режим воркера ниже.
Проверено на
- PHP 8.5.8 — NTS, embed SAPI
- Rapira 0.6.0
- Скелет laravel/laravel с laravel/framework v13.23.0
Всё, о чём рассказывает эта страница, прогонялось на скелете laravel/laravel с парой добавленных тестовых маршрутов, в классическом режиме с одним рабочим процессом: маршрутизация, сессии, загрузка файлов, тела запросов в JSON и в виде формы, кеш конфигурации и маршрутов, ответы с ошибками и 50 последовательных запросов.
Требования
Вам понадобится установленная Rapira — об этом рассказывает Установка — и приложение на Laravel, которое у вас уже запускается. Ещё на машине нужен обычный PHP CLI: через него запускаются Composer и artisan. Rapira поставляет PHP библиотекой (libphp), а не командой php, поэтому эти шаги выполняются на вашем системном PHP, который Rapira не использует и не трогает.
Перед первым запуском проверьте расширения для работы с базой данных: свежий скелет laravel/laravel по умолчанию берёт базу SQLite, а сессии, кеш и очередь складывает туда же, в базу, — значит, ему нужен pdo_sqlite. В PHP из релизов Rapira он есть: PDO, pdo_sqlite и sqlite3 входят в набор расширений релизной сборки, который перечислен на странице Установка. Если вы запускаете Rapira с PHP собственной сборки, проследите, чтобы эти расширения попали в строку configure — через это проводит Сборка из исходников, — либо вместо этого переключите Laravel на файловые и синхронные драйверы: SESSION_DRIVER=file, CACHE_STORE=file, QUEUE_CONNECTION=sync. Именно на этой комбинации проверялось всё, что написано на этой странице.
Как это запустить
Классический режим включается явно, поэтому команда прямо его называет:
rapira serve --classic public/index.php[pool]
entrypoint = "public/index.php"
classic = true
processes = 4
[http]
listen = "127.0.0.1:8000"С файлом конфигурации команда выглядит как rapira serve --config rapira.toml, а относительный entrypoint отсчитывается от каталога самого файла. Полный список ключей со значениями по умолчанию собран в Конфигурации.
Rapira выполняет фронт-контроллер с нуля на каждый запрос, поэтому жизненный цикл фреймворка ровно такой же, как под php-fpm: резидентного состояния нет, сбрасывать между запросами нечего. Прогретым остаётся OPcache: PHP стартует один раз в мастер-процессе, ещё до того как форкнется первый воркер, поэтому все воркеры пользуются общим кешем скомпилированных скриптов — и для вашего кода, и для дерева vendor/. Как это устроено, разбирает Классический режим.
Для продакшена сначала соберите кеши фреймворка. Обе команды проверены в классическом режиме: один и тот же набор проверок проходил одинаково и с кешем, и без него.
php artisan config:cache
php artisan route:cacheМаршрутизация и URL
Rapira не сопоставляет URL с файлами: каждый запрос выполняет фронт-контроллер, а путь для маршрутизации Laravel берёт из $_SERVER['REQUEST_URI']. Маршрутизация, собственная страница 404 Laravel для несовпавших путей и генерация адресов через url() — всё это проверено: получаются аккуратные абсолютные адреса без index.php внутри, причём ни подменять $_SERVER, ни править настройки маршрутов и URL для этого не нужно.
Встроенный в скелет маршрут проверки здоровья /up отвечает 200, так что на него можно нацелить балансировщик или проверку состояния контейнера. Для статики перед Rapira нужно что-то поставить — CDN или обратный прокси, настройку которого описывает страница Запуск в продакшене. Rapira слушает открытый HTTP и оставляет $_SERVER['HTTPS'] пустым независимо от X-Forwarded-Proto, поэтому, если TLS терминируется на прокси, настройте в Laravel доверенные прокси — иначе url() будет выдавать ссылки на http://.
Сессии, CSRF и формы
Сессии проверены на файловом драйвере: кука сессии уходит клиенту, возвращается со следующим запросом, и у каждого клиента своя сессия. CSRF не требует настройки: токен лежит в сессии, а каждый запрос получает ту же семантику свежего процесса, что и под php-fpm. Отправка форм, тела запросов в JSON и загрузка файлов — всё это проверено на той же конфигурации. Когда маршрут бросает исключение, обработчик исключений Laravel рисует свою обычную 500, а на следующий запрос это никак не влияет.
Режим воркера
Режим воркера для Laravel находится в разработке и пока не поддерживается — запускайте Laravel в классическом режиме. Сроков появления поддержки пока нет.
Причина — в жизненном цикле фреймворка. Контейнер Laravel не рассчитан на то, чтобы своими силами пережить второй запрос: по ходу запроса разрешаются привязки, синглтоны захватывают текущий запрос, наполняется собственная статика фреймворка, и всё это нужно размотать обратно до прихода следующего запроса. Этим размотыванием и занимается Octane (laravel/octane) — собственный пакет Laravel для долгоживущих серверов. Octane работает только на тех серверах, для которых у него есть драйвер, а драйвера Octane у Rapira пока нет.
Дело не в самом режиме: Symfony и Yii3 держат свои приложения резидентными в том же режиме SAPI Worker. Не хватает специфичной для Laravel работы с состоянием между запросами.
Свой скрипт воркера для Laravel написать можно, но держать приложение резидентным — значит руками повторять то, что Octane делает с состоянием: разматывать приходится состояние, размазанное по контейнеру, разрешённым синглтонам, стеку запроса, сессии и аутентификации, а ещё по собственной статике фреймворка, и один пропущенный пункт оборачивается устаревшим объектом запроса или сессией одного пользователя, видимой другому.