Настоящее PHP-приложение и PHP-FPM
В основном блоке файл /my/legacy/first.php содержал HTML и отдавался без интерпретатора. Теперь рассмотрим другой случай: сайт действительно выполняет PHP-код. Для этого добавим отдельное учебное приложение, не меняя режим статической библиотеки. Такое разделение важно: расширение пути не позволяет само по себе определить назначение файла.
Новый корень стенда — /srv/release-lab-php/current/public. В нём находятся index.php и health.php с настоящим кодом. Основной статический release-lab продолжает жить под своим префиксом. Примеры относятся к отдельному виртуальному сайту или отдельному закрытому окружению. Нельзя поместить исходный PHP в прежний корень, где мы настроили выдачу .php как HTML.
Как проходит запрос
Nginx принимает соединение, выбирает сайт и определяет обработчик пути. Для PHP он передаёт запрос PHP-FPM через FastCGI. FPM управляет рабочими процессами интерпретатора, выполняющими приложение. После выполнения ответ возвращается через Nginx посетителю. Это добавляет новый слой: статический файл может успешно открываться, пока FPM недоступен и PHP-страницы не работают.
У FPM есть отдельная конфигурация пула: пользователь, адрес прослушивания и ограничения процессов. В учебном варианте используем Unix-сокет, доступный Nginx на той же машине. Публиковать FastCGI-порт наружу не требуется. Значения сокета и пользователя зависят от установленного пакета; путь с версией нельзя переносить на любую систему без проверки. Первичная документация настройки PHP-FPM.
Для штатного пакета PHP 8.3 в выбранном Ubuntu 24.04 часто используется путь /run/php/php8.3-fpm.sock. В этой статье он служит конкретной предпосылкой примера, а не утверждением о текущем сервере ProfessorWeb. Читатель сначала устанавливает выбранную поддерживаемую версию и сверяет настройки пула. Если пакет имеет другую версию или отдельный пул, меняется соответствующий путь, а не произвольные строки приложения.
Минимальное настоящее приложение
Создадим будущий health.php, который возвращает небольшой JSON. Он показывает выполнение кода, потому что сервер должен интерпретировать PHP, а не отдать исходник с угловыми скобками. Номер php-r1 обозначает отдельный прикладной выпуск, чтобы не перепутать его со статическим r1. Читатель заменит его фактическим идентификатором подготовленного результата.
<?php
header('Content-Type: application/json; charset=utf-8');
header('Cache-Control: no-store');
echo json_encode(['release' => 'php-r1', 'component' => 'php-fpm']);
У такого индикатора узкий смысл: интерпретатор выполнил короткий код и вернул ответ. Он не проверяет базу, отправку почты или все маршруты приложения. Не нужно включать в публичный ответ сведения о расширениях, переменных среды и секретах. Для первоначальной проверки достаточно узнать компонент и выпуск. Диагностику расширенной конфигурации выполняют через закрытые инструменты, а не публичную страницу с полным описанием машины.
Связать путь с FastCGI
Ниже фрагмент серверного блока отдельного PHP-сайта. TLS, имя и журналы добавляются по уже изученному образцу. try_files до передачи проверяет наличие указанного файла, поэтому произвольный путь не отправляется в интерпретатор как существующий скрипт. SCRIPT_FILENAME показывает FPM абсолютный путь к выбранному файлу, а $realpath_root разрешает ссылку текущего выпуска.
root /srv/release-lab-php/current/public;
index index.php;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
try_files $uri =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
fastcgi_params должен соответствовать установленной конфигурации Nginx. Некоторые готовые включения уже задают часть параметров; читатель смотрит их содержание, чтобы не создавать противоречивые значения. Это не конфигурация произвольного framework с единой точкой входа. Для такого приложения маршрутизация через index.php описывается отдельно, а сейчас каждый PHP-путь соответствует реальному файлу. Модуль FastCGI Nginx.
Разобрать ожидаемые ответы
Будущий GET к health.php должен вернуть JSON с php-r1, а запрос несуществующего скрипта — 404. Если браузер показывает исходный PHP, немедленно возвращаются к режиму обслуживания изолированного сайта: запрос попал в статический обработчик. Если возникает 502, проверяют FPM, адрес сокета и права подключения. Ошибка выполнения PHP может дать другой статус и появиться в прикладном журнале. Разные симптомы не исправляются одной случайной перезагрузкой.
Права каталога кода должны позволять процессу FPM читать файлы, а не обязательно изменять их. Nginx нужен доступ к статическим ресурсам и сокету. Пользователь FPM может отличаться от владельца выпусков: это ограничивает последствия прикладной ошибки. Если приложение позднее принимает загрузки, им выделяют отдельное место, где нельзя выполнять загруженный PHP. Сам факт расширения .jpg также не является полноценной проверкой содержимого загрузки.
Выпуск приложения отличается от выпуска статики
У PHP появляются зависимости: расширения, настройки интерпретатора и библиотеки. Архив кода должен соответствовать подготовленному окружению. Ошибка отсутствующего расширения не исправляется сменой DNS. Зависимости фиксируют в документах проекта, а установку проверяют до переключения. Если используется менеджер пакетов приложения, его результат относится к артефакту или к явно описанному подготовительному шагу, а не выполняется случайно при первом посещении.
Также существует кеш исполняемого кода OPcache. После выбора другого каталога важно знать, как установленный режим определяет свежесть файлов. Уникальные пути выпусков облегчают различение, но не заменяют проверку эффективных настроек и поведения процессов. При необходимости применяют согласованный перезапуск или другой механизм обновления. Его последствия для активных запросов учитывают как часть изменения, а не обещают, что одна ссылка обновила абсолютно всё.
Отдельно полезно проверить намеренно отсутствующий скрипт. Если он получает главную приложения с кодом 200, изменилось правило маршрутизации, а не только обработчик PHP. Для нашего простого стенда ожидается 404; framework с единой точкой входа потребует другого явно описанного ожидания.
Ограничения размера пула
Число рабочих процессов выбирают с учётом памяти и длительности запросов. Больше процессов не всегда означает быстрее: при нехватке памяти появляются вытеснение и отказы. Для учебного индикатора нагрузки почти нет, но реальное приложение может ждать базу или внешний сервис. Сначала наблюдают потребление и очередь, затем меняют параметры. Нельзя копировать большое значение из примера для другого сервера без оценки ресурсов.
В итоге мы получили отдельный контур настоящего PHP и понятную цепочку диагностики: Nginx, FastCGI, FPM, код. Статические старые URL остаются в прежнем режиме. Следующий урок покажет другую прикладную модель — долгоживущий WSGI-процесс под управлением systemd, где запуск приложения становится самостоятельной частью сопровождения.