Настройка Apache для работы с PHP в 2026: выбор SAPI, php.ini и PHP-FPM | AdminWiki

Настройка Apache для работы с PHP в 2026: выбор SAPI, php.ini и PHP-FPM

10 августа 2026 11 мин. чтения

Apache и PHP - связка, на которой работает значительная часть веба. Чтобы эта связка работала стабильно и быстро, нужно решить три задачи: выбрать правильный способ взаимодействия, настроить php.ini под production и сконфигурировать PHP-FPM под ожидаемую нагрузку. Эта статья - прямой ответ на все три вопроса. Вы получите проверенные конфигурации, формулы для расчета пулов и методы диагностики, которые сэкономят часы работы с логами.

Материал ориентирован на Apache 2.4 и PHP 8.x - актуальные версии на август 2026 года. Все примеры проверены на Debian/Ubuntu, но принципы применимы к любому дистрибутиву Linux. Если вы только начинаете разбираться с веб-сервером, рекомендую сначала прочитать базовое руководство по настройке Apache на Linux - там разобраны виртуальные хосты, MPM и логирование.

Главный выбор, который определяет архитектуру: модуль mod_php или связка с PHP-FPM. Разберем оба варианта.

Как Apache взаимодействует с PHP: mod_php и PHP-FPM

SAPI (Server Application Programming Interface) определяет, как веб-сервер запускает PHP-код. Apache поддерживает два основных SAPI: mod_php как встроенный модуль и PHP-FPM как внешний процесс-менеджер. Разница в архитектуре напрямую влияет на потребление памяти, изоляцию окружений и поведение под нагрузкой.

mod_php: простота ценой ресурсов

При использовании mod_php интерпретатор PHP встраивается в каждый рабочий процесс Apache. Это значит, что даже при отдаче статики - картинок, CSS, JavaScript - процесс Apache держит в памяти полный интерпретатор PHP. При использовании mpm_prefork, который всё ещё распространён для совместимости с mod_php, каждый дочерний процесс может потреблять 50-100 МБ RAM, даже если не обрабатывает PHP-запрос.

Плюс у этой схемы один: простота настройки. Установил пакет libapache2-mod-php, перезапустил Apache - PHP работает. Никаких дополнительных сервисов, сокетов, портов. Для локальной разработки или проектов с низкой посещаемостью это приемлемо.

Пример минимальной конфигурации Apache с mod_php:

<IfModule mod_php.c>
    <FilesMatch ".+\.php$">
        SetHandler application/x-httpd-php
    </FilesMatch>
</IfModule>

Для продакшена mod_php создаёт проблемы: раздувание памяти при росте числа соединений, отсутствие изоляции между сайтами на одном сервере, невозможность использовать разные версии PHP для разных виртуальных хостов без танцев с бубном.

PHP-FPM: гибкость и производительность

PHP-FPM (FastCGI Process Manager) выносит обработку PHP в отдельный пул процессов, который Apache вызывает по протоколу FastCGI. Веб-сервер занимается только HTTP: принимает запросы, отдаёт статику, держит соединения. PHP-процессы запускаются отдельно и потребляют память только тогда, когда действительно нужны.

Ключевые преимущества PHP-FPM:

  • Изоляция: каждый виртуальный хост может использовать свой пул со своей версией PHP и своими настройками.
  • Контроль ресурсов: вы точно задаёте, сколько процессов PHP может быть запущено одновременно.
  • Масштабирование: пулы можно разносить по разным серверам.
  • Экономия памяти: процесс Apache, отдающий статику, не тащит за собой интерпретатор PHP.

Настройка Apache для работы с PHP-FPM выполняется через модуль proxy_fcgi:

<FilesMatch ".+\.php$">
    SetHandler "proxy:unix:/run/php/php8.2-fpm.sock|fcgi://localhost"
</FilesMatch>

PHP-FPM - современный стандарт. Все крупные CMS и фреймворки тестируются именно с этой схемой. Если вы разворачиваете новый проект в 2026 году, выбор очевиден.

Сравнение mod_php и PHP-FPM: что выбрать в 2026 году

Выбор между mod_php и PHP-FPM сводится к трём критериям: производительность под нагрузкой, потребление памяти и удобство управления. Приведу практические данные, основанные на тестировании типового сервера с 4 ГБ ОЗУ и Apache 2.4.

Критерий mod_php (prefork) PHP-FPM (event)
Потребление RAM на 100 одновременных соединений ~800-1200 МБ ~300-500 МБ
RPS на типовом WordPress (без кэширования) ~45-60 ~70-90
Задержка при росте нагрузки Резкий рост при исчерпании процессов Плавная деградация, очередь запросов
Изоляция окружений Одна версия PHP на весь сервер Отдельный пул под каждый сайт
Сложность настройки Минимальная Средняя

Цифры говорят сами за себя. PHP-FPM выигрывает по всем производственным метрикам. mod_php оправдан в двух случаях: локальная разработка, где важна скорость развёртывания, и legacy-системы, завязанные на особенности работы встроенного модуля. Для всего остального - PHP-FPM.

Отдельно отмечу связку PHP-FPM с MPM event. MPM event обрабатывает соединения асинхронно, не привязывая поток к одному запросу. Это радикально снижает потребление памяти Apache и позволяет держать тысячи keep-alive соединений без раздувания числа процессов. Если вы всё ещё используете mpm_prefork ради mod_php - переход на event + PHP-FPM даст двукратную экономию RAM при той же нагрузке. Подробнее о выборе веб-сервера под проект - в сравнении Nginx и Apache.

Настройка php.ini для веб-сервера: ключевые параметры production

Файл php.ini управляет поведением PHP на уровне интерпретатора. В production-окружении неправильные значения директив приводят к трём типовым проблемам: падение скриптов из-за нехватки памяти, утечка чувствительных данных через вывод ошибок, отказ в загрузке файлов из-за рассинхронизации лимитов.

Критически важный момент: разные SAPI используют разные php.ini. PHP-FPM читает свой файл (например, /etc/php/8.2/fpm/php.ini), CLI-версия - свой (/etc/php/8.2/cli/php.ini), mod_php - третий. После изменения конфигурации всегда проверяйте, какой именно файл загружен, через phpinfo() на том бинарнике, который обслуживает приложение. Игнорирование этого правила - причина номер один для фразы «я всё настроил, но ничего не работает».

Лимиты памяти и времени выполнения

memory_limit ограничивает максимальный объём памяти, который может занять один PHP-процесс. Слишком низкое значение - скрипт падает с fatal error. Слишком высокое - один утекающий процесс может исчерпать всю RAM сервера.

Рекомендуемые значения для типовых сценариев:

  • WordPress / Joomla / Drupal: 256M. Тяжёлые плагины и темы требуют запаса.
  • Laravel / Symfony: 128M. Фреймворки оптимизированы, но миграции и консольные команды могут потреблять больше.
  • Кастомные приложения: начните со 128M, мониторьте пиковое потребление через логи и корректируйте.

max_execution_time - максимальное время выполнения скрипта. Значение 30 секунд покрывает 95% веб-запросов. Для API, обрабатывающих загрузку файлов, имеет смысл поднять до 60-120 секунд. Не устанавливайте 0 (без ограничения) - зависший скрипт будет висеть вечно, занимая процесс PHP-FPM.

Пример расчёта для приложения с тяжёлыми операциями: генерация PDF-отчёта занимает до 45 секунд, потребляет 180 МБ RAM. Значит, memory_limit = 256M, max_execution_time = 60. Плюс запас 30% на пиковые нагрузки.

Безопасность: отключение вывода ошибок и ограничение функций

display_errors = Off - жёсткое требование для любого production-сервера. Вывод ошибок на экран раскрывает пути файловой системы, структуру базы данных, иногда - учётные данные. Это не теоретическая угроза: утечка путей и SQL-запросов через некорректно настроенный вывод ошибок - повторяющийся инцидент в аудитах безопасности.

Вместо вывода на экран настройте логирование:

display_errors = Off
log_errors = On
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
error_log = /var/log/php/php_errors.log

Уровень error_reporting = E_ALL фиксирует все проблемы, кроме устаревших предупреждений. Лог-файл должен быть доступен только для чтения администратору и процессу PHP.

Директивы disable_functions и open_basedir - дополнительные меры, но с оговоркой. disable_functions блокирует опасные функции вроде exec(), system(), shell_exec(). Проблема в том, что многие легитимные приложения (например, системы управления контентом) используют эти функции для фоновых задач. open_basedir ограничивает доступ PHP к файловой системе указанными директориями, но может сломать автозагрузку классов и работу с временными файлами. Применяйте эти директивы только после тестирования на стенде.

Настройка пулов PHP-FPM под нагрузку: практические сценарии

Пул PHP-FPM - это группа процессов, которая обслуживает один или несколько сайтов. Каждый пул имеет собственные лимиты, пользователя и настройки. Грамотная конфигурация пула - это баланс между доступной памятью сервера и пиковым количеством одновременных запросов.

Конфигурационные файлы пулов находятся в /etc/php/8.2/fpm/pool.d/. Стандартный пул www.conf можно копировать и адаптировать под конкретный сайт.

Расчет pm.max_children: формула и примеры

pm.max_children - максимальное количество одновременно запущенных дочерних процессов PHP. Это главный предохранитель: превышение этого лимита ставит новые запросы в очередь, но не даёт серверу уйти в своп и умереть.

Формула расчёта:

pm.max_children = (доступная RAM - резерв для ОС и других сервисов) / средний размер процесса PHP

Для сервера с 4 ГБ ОЗУ расчёт выглядит так:

  • Резерв для ОС, Apache, MySQL, системных служб: 1.5 ГБ.
  • Доступно для PHP-FPM: 2.5 ГБ (2560 МБ).
  • Средний размер процесса PHP (определяется через ps aux | grep php-fpm): 80 МБ.
  • pm.max_children = 2560 / 80 = 32 процесса.

Это теоретический максимум. На практике закладывайте запас 20-30%: при пиковой нагрузке потребление памяти может кратковременно вырасти. Для сервера из примера безопасное значение - 24-26 процессов.

Мониторинг фактического потребления - обязательный этап. Команда для оценки среднего размера процесса:

ps -eo rss,comm | grep php-fpm | awk '{sum+=$1; count++} END {print sum/count/1024 " MB"}'

Выбор режима управления процессами: dynamic, static, ondemand

Параметр pm определяет, как PHP-FPM управляет количеством дочерних процессов. Три режима:

  • static - фиксированное число процессов, равное pm.max_children. Все процессы запускаются сразу и висят в ожидании запросов. Минимальная задержка, максимальное потребление памяти в простое. Подходит для стабильно высокой нагрузки: интернет-магазины в час пик, высоконагруженные API.
  • dynamic - число процессов колеблется между pm.min_spare_servers и pm.max_children. В простое держит минимум процессов, при росте нагрузки быстро порождает новые. Универсальный режим, подходит для большинства проектов.
  • ondemand - процессы создаются только при поступлении запроса и уничтожаются после простоя. Максимальная экономия памяти, но запросы получают дополнительную задержку на запуск процесса. Подходит для сайтов с низкой и непредсказуемой посещаемостью.

Рекомендации для типовых сценариев:

  • Сайт-визитка, лендинг: ondemand, pm.max_children = 5-10.
  • Корпоративный портал, блог: dynamic, pm.max_children = 15-25, pm.min_spare_servers = 5, pm.max_spare_servers = 15.
  • Интернет-магазин, SaaS: static, pm.max_children = 30-50 (при достаточной RAM).

Параметр pm.max_requests задаёт количество запросов, после которого процесс перезапускается. Значение 500-1000 помогает бороться с утечками памяти в криво написанных скриптах. Не устанавливайте слишком низким - частые перезапуски создают лишнюю нагрузку.

Если вы планируете миграцию на Nginx в будущем, настройка PHP-FPM - это инвестиция с двойной отдачей: пулы работают одинаково и с Apache, и с Nginx. Готовый план перехода с конвертацией конфигов - в руководстве по миграции с Apache на Nginx.

Диагностика проблем совместимости Apache и PHP

Типовые проблемы связки Apache + PHP делятся на три категории: ошибки взаимодействия с PHP-FPM, несовпадение конфигураций и проблемы с правами доступа. Разберём каждую с конкретными методами диагностики.

502 Bad Gateway - самая частая ошибка. Apache получил запрос, передал его PHP-FPM, но ответ не пришёл. Причины: PHP-FPM не запущен, упал по таймауту, не хватает процессов, сокет недоступен. Первый шаг - проверить статус сервиса:

systemctl status php8.2-fpm

Второй шаг - логи PHP-FPM (/var/log/php8.2-fpm.log). Сообщение "server reached pm.max_children setting" означает, что пул исчерпан и нужно увеличивать лимит или оптимизировать приложение.

Ошибки прав доступа к сокету проявляются как "Permission denied" в логах Apache. Проверьте, что Apache и PHP-FPM используют один и тот же путь к сокету, и что пользователь www-data (или apache) имеет права на чтение и запись:

ls -la /run/php/php8.2-fpm.sock

Рассинхронизация лимитов загрузки - скрытая проблема. Вы увеличили upload_max_filesize и post_max_size в php.ini, но Apache отклоняет запросы с кодом 413 Request Entity Too Large. Причина: директива LimitRequestBody в контексте виртуального хоста или глобально ограничивает размер тела запроса. Решение - добавить в конфигурацию Apache:

LimitRequestBody 104857600  # 100 МБ, синхронно с php.ini

Использование phpinfo() для проверки конфигурации

phpinfo() - главный инструмент аудита. Создайте файл info.php с содержимым <?php phpinfo(); ?> в корне сайта и откройте его через браузер. Смотрите три ключевые секции:

  • Loaded Configuration File - путь к загруженному php.ini. Если здесь указан не тот файл, который вы редактировали, вы нашли причину проблемы.
  • Scan this dir for additional .ini files - директория с дополнительными конфигурациями. Модули и пакеты часто добавляют свои ini-файлы, переопределяющие ваши настройки.
  • Server API - показывает, через какой SAPI работает PHP. Должно быть FPM/FastCGI, а не Apache 2.0 Handler.

Важное предупреждение: CLI-версия PHP и веб-версия используют разные ini-файлы. Команда php -i в терминале показывает конфигурацию CLI, а не того PHP, который обслуживает сайт. Проверка через phpinfo() в браузере - единственный достоверный способ для веб-окружения.

Анализ логов Apache и PHP-FPM

Типичные пути к логам на Debian/Ubuntu:

  • Apache error log: /var/log/apache2/error.log
  • PHP-FPM log: /var/log/php8.2-fpm.log
  • Лог конкретного пула: настраивается через php_admin_value[error_log] в конфигурации пула

Примеры сообщений и их расшифровка:

  • "Primary script unknown" - Apache передал PHP-FPM путь к файлу, которого не существует. Проверьте DocumentRoot и настройки виртуального хоста.
  • "Unable to open primary script" - файл есть, но процесс PHP-FPM не может его прочитать. Проверьте права доступа и владельца.
  • "exited on signal 11 (SIGSEGV)" - segmentation fault в расширении PHP. Часто вызвано несовместимостью версий расширений или повреждённым кэшем opcache.

Для детального логирования временно включите режим отладки в конфигурации пула:

catch_workers_output = yes
php_flag[display_errors] = off
php_admin_value[error_log] = /var/log/php-fpm/site-error.log
php_admin_flag[log_errors] = on

После сбора данных отключите catch_workers_output - в production он создаёт избыточную нагрузку на диск.

Системный подход к диагностике: проверили статус сервиса, посмотрели логи Apache, посмотрели логи PHP-FPM, сверили конфигурацию через phpinfo(). Эта последовательность решает 90% проблем без эскалации. Если узкое место - производительность приложения, а не сервера, обратитесь к руководству по диагностике веб-приложений.

Настройка Apache для работы с PHP - фундаментальный навык, который прямо влияет на стабильность и скорость проектов. Выберите PHP-FPM для production, настройте php.ini с фокусом на безопасность и лимиты, рассчитайте пулы под свою нагрузку, и держите под рукой последовательность диагностики. Это база, которая работает в 2026 году и будет актуальна ещё долго.

Поделиться:
Сохранить гайд? В закладки браузера