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.