Apache и PHP: конфигурация веб-сервера для выполнения скриптов

Раздел: Настройка сервера -> Веб-серверы

Настройка Apache для PHP

Основным и наиболее производительным решением для связки Apache и PHP является использование модуля mod_php (также известного как libapache2-mod-php в Debian/Ubuntu). Этот модуль встраивает интерпретатор PHP непосредственно в процесс Apache, что минимизирует накладные расходы на запуск отдельных процессов. Решение подходит для большинства стандартных сайтов.

Установка на Debian/Ubuntu:

sudo apt update
sudo apt install apache2 php libapache2-mod-php php-mysql

Пояснение: пакет libapache2-mod-php автоматически включает модуль в конфигурацию Apache. После установки необходимо перезапустить сервер:

sudo systemctl restart apache2

Настройка обработчика PHP: обычно модуль автоматически связывает файлы .php с обработчиком. Проверить это можно в файле /etc/apache2/mods-available/php8.?.conf (версия может отличаться). Там обычно присутствует директива:

<FilesMatch \.php$>
    SetHandler application/x-httpd-php
</FilesMatch>

Проблема: после установки Apache не обрабатывает PHP, а показывает исходный код. Чаще всего модуль не включён. Проверка:

sudo a2enmod php8.1   # замените на вашу версию
sudo systemctl restart apache2

Другая типичная ошибка - отсутствие DirectoryIndex. Убедитесь, что в конфигурации виртуального хоста указано DirectoryIndex index.php index.html.

Как изолировать процессы PHP и повысить производительность при высоких нагрузках?

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

Установка и настройка на Debian/Ubuntu:

sudo apt install php-fpm php-mysql
sudo a2enmod proxy_fcgi setenvif
sudo systemctl restart apache2

Конфигурация виртуального хоста для использования PHP-FPM:

<VirtualHost *:80>
    ServerName example.com
    DocumentRoot /var/www/example

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

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

Проблема: ошибка 503 Service Unavailable. Проверьте, что сокет PHP-FPM существует и имеет правильные права. Команда для проверки:

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

Если сокет отсутствует, запустите службу:

sudo systemctl start php8.1-fpm

Также убедитесь, что пользователь www-data имеет доступ к сокету (обычно права 666 или владелец совпадает).

Как запускать PHP от имени отдельного пользователя (например, для каждого сайта)?

Можно использовать PHP-FPM с отдельными пулами. Создайте файл пула /etc/php/8.1/fpm/pool.d/example.conf:

[example]
user = siteuser
group = siteuser
listen = /run/php/php8.1-fpm-example.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

Затем в виртуальном хосте укажите этот сокет:

SetHandler "proxy:unix:/run/php/php8.1-fpm-example.sock|fcgi://localhost/"

Проблема: пул не стартует. Проверьте синтаксис конфигурации FPM:

sudo php-fpm8.1 -t

Если ошибок нет, перезапустите службу:

sudo systemctl restart php8.1-fpm

Если требуется совместимость со старыми настройками или ограничениями безопасности?

Использование CGI (mod_cgi) - самый старый и ресурсоёмкий способ. Подходит для тестовых окружений или специфичных конфигураций.

Включение mod_cgi:

sudo a2enmod cgi
sudo systemctl restart apache2

Настройка с помощью ScriptAlias:

ScriptAlias /php-cgi/ /usr/bin/php-cgi
<Directory "/usr/bin">
    Require all denied
</Directory>

Обычно CGI используется через .htaccess в каталоге сайта:

AddHandler cgi-script .php
Action cgi-script /php-cgi/php-cgi

Проблема: ошибка 500 Internal Server Error. Чаще всего неправильные права на исполняемый файл PHP. Проверьте:

ls -l /usr/bin/php-cgi

Должен быть установлен бит исполнения для www-data. Другая причина - отсутствие заголовка Content-Type в самом скрипте.

Дополнительные примеры конфигурации

Пример 1. Виртуальный хост с mod_php для двух сайтов на одном сервере

Пример
<VirtualHost *:80>
    ServerName site1.local
    DocumentRoot /var/www/site1
    <Directory /var/www/site1>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

<VirtualHost *:80>
    ServerName site2.local
    DocumentRoot /var/www/site2
    <Directory /var/www/site2>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

Результат: Apache обрабатывает PHP-скрипты в обоих каталогах автоматически через mod_php. Проверить можно создав файл info.php с вызовом phpinfo().

Пример 2. Настройка PHP-FPM с ограничением памяти и времени выполнения для конкретного пула

Пример
[pool_limited]
user = limiteduser
group = limiteduser
listen = /run/php/php8.1-limited.sock
listen.owner = www-data
listen.group = www-data
pm = ondemand
pm.max_children = 3
pm.process_idle_timeout = 10s
php_admin_value[memory_limit] = 64M
php_admin_value[max_execution_time] = 30

Пояснение: php_admin_value задаёт параметры, которые нельзя переопределить через ini_set() в скрипте. Это полезно для изоляции клиентских сайтов.

Результат: скрипты в этом пуле не смогут использовать более 64 МБ памяти и будут прерваны после 30 секунд выполнения. Проверка через скрипт:

Пример
echo ini_get('memory_limit');   // выведет 64M

Пример 3. Использование .htaccess для переопределения обработчика PHP на каталог

Пример
# .htaccess в каталоге /var/www/example/secure
# Принудительно обрабатывать все файлы как PHP (например, для файлов без расширения)
AddType application/x-httpd-php .php .php5 .html
# Отключение обработчика для подкаталога
<FilesMatch "\.txt$">
    SetHandler none
</FilesMatch>

Результат: файлы .html теперь обрабатываются как PHP. Если в каталоге есть readme.txt, он будет отдан как текст без обработки. Проверка: запрос к example.html выполнит PHP-код внутри него.

Пример 4. Изменение php.ini для Apache через конфигурацию виртуального хоста

Пример
<VirtualHost *:80>
    ServerName myapp.local
    DocumentRoot /var/www/myapp
    php_value upload_max_filesize 50M
    php_value post_max_size 55M
    php_value max_execution_time 120
    php_flag display_errors on
</VirtualHost>

Пояснение: директивы php_value и php_flag работают только если используется mod_php. Для PHP-FPM аналогичные настройки задаются в пуле через php_admin_value.

Результат: приложение в myapp.local сможет загружать файлы до 50 МБ, время выполнения скриптов увеличено до 2 минут, включён показ ошибок. Проверить можно через тестовый скрипт:

Пример
<?php
phpinfo(INFO_GENERAL);
?>
Отобразится секция Configuration, где видны установленные значения.

Пример 5. Установка phpMyAdmin с Apache и mod_php

Пример
sudo apt install phpmyadmin
# Во время установки выбрать Apache2 и настроить базу данных
# После установки проверить файл /etc/apache2/conf-available/phpmyadmin.conf
sudo a2enconf phpmyadmin
sudo systemctl reload apache2

Проблема: ошибка 500 при входе. Проверить логи Apache:

Пример
sudo tail -f /var/log/apache2/error.log

Часто требуется установить модуль mbstring:

Пример
sudo apt install php-mbstring

Результат: phpMyAdmin будет доступен по адресу http://localhost/phpmyadmin.

Apache сервер PHP - comments

En
Php apache server (php)