Конфигурирование Apache для работы с PHP

Раздел: Администрирование веб-сервера -> Настройка модуля Apache

Руководство по настройке взаимодействия Apache и PHP

Интеграция веб-сервера Apache с интерпретатором PHP может быть реализована несколькими способами. Выбор метода зависит от версий программного обеспечения, требований к производительности, безопасности и удобства администрирования. Все варианты предполагают установку соответствующих модулей и настройку конфигурационных файлов.

Вопрос: Как настроить современную производительную связку Apache с PHP, используя отдельный процесс FastCGI?

Наиболее эффективным решением признаётся использование PHP-FPM (FastCGI Process Manager) совместно с модулем mod_proxy_fcgi. Данный подход позволяет разделить процессы Apache и PHP, что повышает стабильность и безопасность, а также даёт возможность применять MPM event или worker. Случаи использования: высоконагруженные проекты, окружения с разными версиями PHP для разных виртуальных хостов, требования к изоляции.

  1. Установите PHP-FPM и включите необходимые расширения. В дистрибутивах на базе Debian/Ubuntu команда:
    sudo apt install php-fpm php-mysql php-xml php-mbstring

    Php apache модуль (настройка модуля apache для php)

  2. Активируйте модуль прокси:
    sudo a2enmod proxy_fcgi proxy
  3. Настройте пул в файле /etc/php/8.x/fpm/pool.d/www.conf. Обратите внимание на параметры listen, pm.max_children и user.
  4. В конфигурации виртуального хоста Apache добавьте директиву для проксирования запросов к сокету PHP-FPM:
    <VirtualHost *:80>
        ServerName example.com
        DocumentRoot /var/www/example
        <FilesMatch \.php$>
            SetHandler "proxy:unix:/var/run/php/php8.2-fpm.sock|fcgi://localhost"
        </FilesMatch>
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
    </VirtualHost>
  5. Перезапустите оба сервиса:
    sudo systemctl restart php8.2-fpm apache2

Пояснение: директива SetHandler указывает Apache передавать все запросы с расширением .php в Unix-сокет. Пул PHP-FPM должен быть доступен по тому же пути. Преимущества: производительность выше, чем у встроенного модуля при одновременных запросах; возможность тонкой настройки ресурсов каждого пула.

Типичные проблемы и их решения:

  • Ошибка 502 Bad Gateway - сокет не найден или недоступен. Проверьте listen в конфигурации пула, права на сокет (chmod 777 /var/run/php/php8.2-fpm.sock или установите listen.mode=0660).
  • Конфликт с mod_php - если модуль mod_php уже включён, отключите его командой sudo a2dismod php8.2. Иначе директивы могут конфликтовать.
  • Медленная работа из-за неверного MPM - убедитесь, что используется MPM event/worker, а не prefork. Включите командой sudo a2enmod mpm_event и отключите prefork.
  • SELinux блокирует соединение - установите соответствующий контекст: sudo setsebool -P httpd_can_network_connect 1 или semanage fcontext -a -t httpd_var_run_t /var/run/php-fpm/*.sock; restorecon -Rv /var/run/php-fpm/.

Вариант с традиционным модулем mod_php (PHP как модуль Apache)

Вопрос: Как использовать встроенный интерпретатор PHP, работающий непосредственно в процессах Apache?

Данный метод подходит для простых конфигураций, где не требуется высокая производительность при большом количестве параллельных запросов. Ограничение: необходимо использовать MPM prefork, так как mod_php не является потокобезопасным. Случаи использования: старые проекты, локальные серверы разработки, среды с одним виртуальным хостом.

  1. Установите пакет с модулем Apache для PHP. Например, для Debian/Ubuntu:
    sudo apt install php libapache2-mod-php
  2. Активируйте модуль:
    sudo a2enmod php8.2
  3. Переключите MPM на prefork (если используется другой):
    sudo a2dismod mpm_event mpm_worker
    sudo a2enmod mpm_prefork
  4. Настройте обработку .php файлов. Обычно это уже сделано по умолчанию, но можно добавить в конфигурацию виртуального хоста:
    <FilesMatch \.php$>
        SetHandler application/x-httpd-php
    </FilesMatch>
  5. Перезапустите Apache:
    sudo systemctl restart apache2

Возможные проблемы:

  • Повышенное потребление памяти - каждый процесс prefork содержит копию интерпретатора PHP. Для уменьшения памяти настройте MaxRequestWorkers и KeepAliveTimeout.
  • Конфликт с другими модулями - mod_php не совместим с mpm_event и mpm_worker. Убедитесь, что они отключены.
  • Ошибка прав доступа - скрипты выполняются от пользователя www-data, что может не совпадать с владельцем файлов. Используйте suPHP или ruid2 для изменения.

Вариант с mod_fcgid (альтернативный FastCGI-интерфейс)

Вопрос: Как организовать взаимодействие Apache с PHP через FastCGI, используя модуль mod_fcgid?

Модуль mod_fcgid предоставляет другой способ запуска внешних FastCGI-процессов, отличный от нестандартного mod_proxy_fcgi. Он может быть полезен, если требуется управлять временем жизни процессов или если mod_proxy_fcgi недоступен. Случаи использования: старые системы, специфические требования к управлению дочерними процессами.

  1. Установите модуль и PHP-FPM (или cgi-версию PHP):
    sudo apt install libapache2-mod-fcgid php-fpm
  2. Активируйте модуль:
    sudo a2enmod fcgid
  3. Настройте обработчик для .php файлов в виртуальном хосте:
    <IfModule mod_fcgid.c>
        FcgidInitialEnv PHP_FCGI_CHILDREN 0
        FcgidInitialEnv PHP_FCGI_MAX_REQUESTS 1000
        AddHandler fcgid-script .php
        FcgidWrapper /usr/bin/php-cgi .php
    </IfModule>
  4. Проверьте права на исполняемый файл и сокет, если используется сокет FPM. Для работы с php-fpm потребуется дополнительный скрипт-обёртка (wrapper).

Типичные ошибки:

  • Ошибка 500 Internal Server Error - часто из-за неправильного пути к FcgidWrapper или отсутствия прав на исполнение. Убедитесь, что php-cgi доступен и файлы .php имеют разрешение 755.
  • Медленная работа в режиме CGI - для каждого запроса запускается отдельный процесс. Рекомендуется использовать php-fpm вместо php-cgi.
  • Конфликт с mpm_prefork - mod_fcgid не требует prefork, но при использовании mpm_prefork могут возникать проблемы с производительностью. Предпочтительнее mpm_worker или event.

Вариант с CGI-обработчиком (mod_cgi)

Вопрос: Как настроить выполнение PHP-скриптов как CGI-программ через стандартный модуль CGI?

Это самый простой, но наименее производительный способ. Подходит для тестов или сред с очень низкой нагрузкой. Каждый запрос запускает интерпретатор заново, что создаёт значительные накладные расходы. Случаи использования: изолированные скрипты без частого вызова.

  1. Установите пакет php-cgi:
    sudo apt install php-cgi
  2. Включите модуль cgi:
    sudo a2enmod cgi
  3. В конфигурации виртуального хоста укажите, что файлы .php обрабатываются как CGI-скрипты:
    <Directory /var/www/example>
        Options +ExecCGI
        AddHandler cgi-script .php
    </Directory>
  4. Убедитесь, что php-cgi доступен по пути /usr/bin/php-cgi. При необходимости укажите ScriptAlias.

Проблемы:

  • Ошибка 403 Forbidden - если не установлен параметр Options +ExecCGI или файлы не имеют прав на выполнение (chmod +x).
  • Нет сессий и глобальных переменных - в CGI-режиме не поддерживаются общие ресурсы между запросами, что может потребовать ручного старта сессии.
  • Высокая нагрузка на сервер - каждый запрос порождает новый процесс, что быстро исчерпывает ресурсы.

Расширенные примеры конфигурации и их результаты

Пример настройки PHP-FPM с использованием TCP-сокета вместо Unix-сокета

В некоторых окружениях (например, при разделении Apache и PHP на разных хостах) необходимо использовать TCP-соединение. Для этого измените параметр listen в пуле и директиву SetHandler.

Конфигурация пула /etc/php/8.x/fpm/pool.d/www.conf:

Пример
listen = 127.0.0.1:9000
listen.allowed_clients = 127.0.0.1

Виртуальный хост Apache:

Пример
<VirtualHost *:80>
    ServerName example.com
    DocumentRoot /var/www/example
    <FilesMatch \.php$>
        SetHandler "proxy:fcgi://127.0.0.1:9000"
    </FilesMatch>
</VirtualHost>

Результат: при обращении к example.com/file.php Apache передаёт запрос по TCP на порт 9000, где его ожидает php-fpm. Ответ возвращается стандартным образом.

Пример настройки нескольких пулов PHP-FPM для разных виртуальных хостов

Пулы создаются отдельными конфигурационными файлами в /etc/php/8.x/fpm/pool.d/. Каждый пул использует свой сокет или порт. В Apache для каждого виртуального хоста указывается соответствующий обработчик.

Пул site1.conf:

Пример
[site1]
user = site1user
listen = /run/php/site1.sock
listen.owner = www-data
listen.group = www-data
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3

Пул site2.conf:

Пример
[site2]
user = site2user
listen = /run/php/site2.sock
listen.owner = www-data
listen.group = www-data
pm = ondemand
pm.max_children = 10
pm.process_idle_timeout = 10s

Виртуальные хосты Apache:

Пример
<VirtualHost *:80>
    ServerName site1.local
    DocumentRoot /var/www/site1
    <FilesMatch \.php$>
        SetHandler "proxy:unix:/run/php/site1.sock|fcgi://localhost"
    </FilesMatch>
</VirtualHost>

<VirtualHost *:80>
    ServerName site2.local
    DocumentRoot /var/www/site2
    <FilesMatch \.php$>
        SetHandler "proxy:unix:/run/php/site2.sock|fcgi://localhost"
    </FilesMatch>
</VirtualHost>

Результат: сайт1 работает с динамическим пулом, сайт2 с пулом ondemand (процессы создаются по требованию и завершаются после простоя). Изоляция пользователей и ресурсов.

Пример настройки mod_php с ограничением ресурсов через php.ini

При использовании mod_php параметры PHP задаются глобально в php.ini или в .htaccess с помощью директив php_value и php_admin_value.

Файл .htaccess в корне сайта:

Пример
php_value memory_limit 128M
php_value upload_max_filesize 20M
php_value post_max_size 25M
php_value max_execution_time 60

Результат: для всех скриптов внутри каталога устанавливаются лимиты памяти и времени выполнения. Если требуется блокировка изменений для администратора, используются php_admin_value в виртуальном хосте:

Пример
<VirtualHost *:80>
    ServerName example.com
    DocumentRoot /var/www/example
    php_admin_value open_basedir /var/www/example:/tmp
    php_admin_flag engine on
</VirtualHost>

Результат: скрипты ограничены корневым каталогом, что повышает безопасность.

Пример настройки PHP под Windows (Apache + mod_php)

На Windows модуль php7apache2_4.dll загружается в httpd.conf директивами LoadModule и AddHandler. Инструкция:

Пример
LoadModule php7_module "C:/php/php7apache2_4.dll"
AddHandler application/x-httpd-php .php
PHPIniDir "C:/php"

Результат: Apache загружает DLL и обрабатывает .php файлы. Если указан неверный путь, сервер не запустится с ошибкой «Cannot load C:/php/php7apache2_4.dll». Решение - проверить наличие библиотеки и её разрядность (должна совпадать с разрядностью Apache).

Настройка модуля Apache для PHP - comments

En
Php apache модуль (php)