Веб-сервер и PHP: выбор конфигурации

Раздел: Администрирование -> Веб-серверы

Выбор схемы взаимодействия PHP с веб-сервером

Какая конфигурация обеспечивает наибольшую производительность для PHP-приложений?

Наиболее эффективным решением для production-среды считается связка PHP-FPM с Nginx. PHP-FPM (FastCGI Process Manager) управляет пулом процессов PHP, а Nginx выступает как прокси-сервер, передавая запросы на обработку. Такая архитектура уменьшает потребление памяти, позволяет гибко настраивать количество процессов и изолировать ошибки.

# Установка PHP-FPM и Nginx (Ubuntu/Debian)
sudo apt update
sudo apt install nginx php-fpm php-mysql

виртуальный сервер php (настройка виртуального сервера для php)

# Конфигурация пула PHP-FPM (www.conf)
[www]
user = www-data
group = www-data
listen = /run/php/php8.1-fpm.sock
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35

Web сервер php (веб-сервер php)

# Виртуальный хост Nginx (default)
server {
    listen 80;
    server_name example.com;
    root /var/www/html;
    index index.php index.html;
    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.1-fpm.sock;
    }
}

Php apache server (apache сервер php)

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

  • 502 Bad Gateway – PHP-FPM не запущен или сокет не совпадает. Проверка: sudo systemctl status php8.1-fpm.
  • 403 Forbidden – неверные права на корневую директорию. Решение: sudo chown -R www-data:www-data /var/www/html.
  • Медленная работа – нехватка процессов в пуле. Увеличить pm.max_children в соответствии с памятью сервера.

Как быстро запустить PHP-приложение без установки стороннего сервера?

Встроенный веб-сервер PHP подходит для разработки и тестирования. Он запускается одной командой и не требует настройки Apache или Nginx.

# Запуск встроенного сервера на порту 8000
php -S localhost:8000 -t /path/to/project

адрес сервера php (адрес сервера php (как получить в коде))

# Использование маршрутизатора (router.php)
php -S localhost:8080 router.php

Проблемы:

  • Однопоточность – сервер обрабатывает только один запрос за раз, не подходит для нагрузки.
  • Отсутствие поддержки HTTPS, .htaccess и многих расширений безопасности.
  • Для production не рекомендуется.

Как интегрировать PHP непосредственно в Apache?

Модуль mod_php (или libapache2-mod-php) встраивает интерпретатор PHP в каждый процесс Apache. Это простое решение для небольших проектов.

# Установка mod_php на Debian/Ubuntu
sudo apt install apache2 libapache2-mod-php
sudo systemctl restart apache2
# Пример виртуального хоста Apache с поддержкой PHP
<VirtualHost *:80>
    DocumentRoot /var/www/html
    <Directory /var/www/html>
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

Проблемы:

  • Каждый процесс Apache содержит полный интерпретатор PHP, что увеличивает потребление памяти при большом количестве одновременных соединений.
  • Сложнее масштабировать при высоких нагрузках.
  • Конфликты с другими модулями (например, mpm_event несовместим с mod_php).

Как изолировать окружение PHP-приложения с помощью контейнеризации?

Docker позволяет упаковать PHP-приложение, веб-сервер и все зависимости в изолированные контейнеры. Это упрощает развёртывание и обеспечивает воспроизводимость среды.

# docker-compose.yml для Nginx + PHP-FPM
version: '3'
services:
  web:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./src:/var/www/html
      - ./nginx.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - php
  php:
    image: php:8.1-fpm-alpine
    volumes:
      - ./src:/var/www/html

Проблемы:

  • Необходимость настройки сети между контейнерами.
  • Управление конфигурациями через volumes.
  • Для production требуется оркестрация (Kubernetes, Docker Swarm).

Расширенные примеры конфигураций

Ниже приведены детальные примеры, демонстрирующие нестандартные и углублённые настройки взаимодействия PHP и веб-сервера.

Динамическое управление пулом PHP-FPM с ограничением по памяти

Пример конфигурации пула, где количество процессов подстраивается под нагрузку, а максимальное потребление памяти на процесс ограничено.

Пример
[www]
user = www-data
group = www-data
listen = 127.0.0.1:9000
pm = dynamic
pm.max_children = 20
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 8
pm.max_requests = 500
php_admin_value[memory_limit] = 128M
php_admin_value[max_execution_time] = 30
# Проверка активных процессов PHP-FPM
ps aux | grep php-fpm
# Пример вывода:
www-data 12345  0.1  2.3 250000 45000 ? Ss  10:00   0:00 php-fpm: pool www
www-data 12346  0.1  2.1 248000 42000 ? S   10:00   0:00 php-fpm: pool www

Использование .user.ini для переопределения параметров PHP на уровне директории

Вместо глобального php.ini можно задать настройки в файле .user.ini в корне приложения. Это удобно для shared-хостинга.

Пример
# .user.ini (поместить в /var/www/html/)
upload_max_filesize = 50M
post_max_size = 60M
max_execution_time = 120
session.gc_maxlifetime = 14400
# Проверка действующих значений через phpinfo()
# Создайте файл info.php с кодом <?php phpinfo(); ?>
# В секции 'Configuration File (php.ini) Path' увидите директорию, где лежит .user.ini

Встраивание кэширования статики в Nginx для ускорения PHP-сайта

Пример конфигурации, при котором Nginx самостоятельно отдаёт статические файлы (CSS, JS, изображения) с long-кэшем, минуя PHP.

Пример
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
    expires 30d;
    add_header Cache-Control "public, immutable";
    try_files $uri $uri/ /index.php?$query_string;
}
# Проверка заголовков кэша на статическом файле
curl -I https://example.com/style.css
# Пример ответа:
HTTP/2 200
cache-control: public, immutable
expires: Thu, 01 Jan 2026 00:00:00 GMT

Встроенный сервер PHP с пользовательским маршрутизатором

Сценарий router.php позволяет реализовать простую маршрутизацию или обрабатывать запросы к API без полноценного фреймворка.

Пример
<?php
// router.php
$uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
if ($uri === '/api/status') {
    header('Content-Type: application/json');
    echo json_encode(['status' => 'ok', 'time' => time()]);
    exit;
}
return false; // отдать статический файл, если есть
?>
Пример
# Запуск с роутером
php -S 0.0.0.0:8080 router.php
# Запрос к API через curl
curl http://localhost:8080/api/status
# Ответ:
{"status":"ok","time":1712345678}

Настройка chroot для пула PHP-FPM (изоляция файловой системы)

Для усиления безопасности можно ограничить PHP-процессы определённой директорией с помощью chroot.

Пример
[isolated_pool]
user = appuser
group = appgroup
listen = /run/php/isolated.sock
chroot = /var/chroot/app
chdir = /
php_admin_value[open_basedir] = /var/chroot/app
# После перезапуска PHP-FPM процессы не смогут выйти за пределы /var/chroot/app
sudo systemctl restart php8.1-fpm
# Проверка через test.php с кодом <?php echo file_get_contents('/etc/passwd'); ?>
# Должна возникнуть ошибка open_basedir restriction in effect

Веб-сервер PHP - comments

En
Web сервер php (php)