Данная статья представляет собой подробное руководство по настройке связки веб-сервера Nginx и интерпретатора PHP (через PHP-FPM) на сервере с операционной системой семейства Linux. Мы рассмотрим полный цикл: от установки всех необходимых компонентов до их тонкой настройки и оптимизации под высокие нагрузки.

Я полагаю, что у Вас уже есть сервер с которым мы и будем работать, в принципе даже не важно это аренда виртуального сервера или реальный сервер организации, главное это доступные нам ресурсы, от которых мы и будем отталкиваться.

Введение в технологический стек (LEMP)

Стек LEMP (Linux, Nginx, MySQL, PHP) является одним из самых популярных решений для хостинга веб-приложений благодаря своей производительности, стабильности и низкому потреблению ресурсов. В отличие от связки Apache и mod_php, Nginx работает по событийно-ориентированной модели, а PHP обрабатывается отдельным менеджером процессов - PHP-FPM (FastCGI Process Manager). Это позволяет Nginx эффективно выступать в роли прокси-сервера: он принимает запрос от клиента, а если требуется выполнить PHP-код, передает его на обработку PHP-FPM, который может быть настроен для работы через Unix-сокет или TCP-порт.

Часть 1. Установка компонентов

1.1. Подготовка системы и установка Nginx

Перед началом установки необходимо обновить индекс пакетов операционной системы. В примерах будет использоваться Ubuntu/Debian, команды для CentOS/RHEL будут отличаться (использование yum или dnf).

# Обновление списка пакетов
sudo apt update
sudo apt upgrade -y

# Установка Nginx
sudo apt install nginx -y

# Запуск Nginx и добавление в автозагрузку
sudo systemctl start nginx
sudo systemctl enable nginx

# Проверка статуса
sudo systemctl status nginx

После установки веб-сервер должен быть доступен по IP-адресу сервера, отображая приветственную страницу Nginx.

1.2. Установка PHP и PHP-FPM

Далее устанавливаем PHP и менеджер процессов PHP-FPM. Важно установить версию PHP, актуальную на момент настройки (например, 8.1, 8.2 или 8.3). Выбор версии зависит от репозиториев дистрибутива и требований приложения.

# Установка PHP-FPM и необходимых модулей (пример для PHP 8.1)
sudo apt install php-fpm php-mysql php-cli php-curl php-gd php-mbstring php-xml php-zip -y
# Для Ubuntu/Debian с PHP 8.2 пакет будет называться php8.2-fpm и т.д.

Пакет php-fpm автоматически создаст сервис и настроит базовый пул для обработки запросов.

# Запуск PHP-FPM и добавление в автозагрузку (название службы зависит от версии)
sudo systemctl start php8.1-fpm
sudo systemctl enable php8.1-fpm

# Проверка статуса
sudo systemctl status php8.1-fpm

1.3. Установка MySQL/MariaDB (опционально, но рекомендуется)

Для полноценной работы динамических сайтов обычно требуется база данных.

# Установка MySQL сервера
sudo apt install mysql-server -y

# Запуск и обеспечение автозагрузки
sudo systemctl start mysql
sudo systemctl enable mysql

# Запуск скрипта для начальной безопасности (смена root пароля, отключение удаленного доступа и тестовых БД)
sudo mysql_secure_installation

На этом этапе базовая установка всех компонентов стека завершена.

Часть 2. Конфигурация связки Nginx + PHP-FPM

Ключевой момент настройки - заставить Nginx передавать запросы к PHP-файлам на обработку в PHP-FPM.

2.1. Принципы работы Nginx Location

Конфигурация Nginx строится на директивах server (виртуальный хост) и location (правила обработки URI). Для PHP нас интересует блок location ~ \.php$, который обрабатывает все запросы, заканчивающиеся на .php.

2.2. Базовый конфигурационный файл виртуального хоста

Создадим или отредактируем конфигурацию для нашего сайта. В Ubuntu/Debian файлы хостов обычно хранятся в /etc/nginx/sites-available/, а затем ссылаются в /etc/nginx/sites-enabled/.

server {
    # Слушаем 80 порт для IPv4 и IPv6
    listen 80;
    listen [::]:80;

    # Имя сервера (домен)
    server_name your_domain.com www.your_domain.com;

    # Корневая директория сайта (DocumentRoot)
    root /var/www/your_domain/public;

    # Главные индексные файлы
    index index.php index.html index.htm;

    # Логи (опционально)
    access_log /var/log/nginx/your_domain_access.log;
    error_log /var/log/nginx/your_domain_error.log;

    # Основной блок для обработки статических файлов
    location / {
        # Пытаемся найти файл ($uri), если нет - директорию ($uri/),
        # иначе отдаем index.php с аргументами
        try_files $uri $uri/ /index.php$is_args$args;
    }

    # Блок обработки PHP
    location ~ \.php$ {
        # Включаем стандартные параметры FastCGI
        include fastcgi_params;

        # Устанавливаем имя файла скрипта с полным путем
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

        # Важно: предотвращаем передачу несуществующих файлов в PHP-FPM
        try_files $uri =404;

        # Связь с PHP-FPM. Вариант 1: Unix-сокет (быстрее)
        fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;

        # Вариант 2: TCP-сокет (если PHP-FPM на другом сервере или порту)
        # fastcgi_pass 127.0.0.1:9000;
        
        # Таймаут ожидания ответа от PHP-FPM (важно для долгих скриптов)
        fastcgi_read_timeout 300;
    }

    # Запрещаем доступ к скрытым файлам (начинающимся с точки)
    location ~ /\. {
        deny all;
        access_log off;
        log_not_found off;
    }

    # Запрещаем доступ к PHP-файлам в чувствительных директориях (опционально)
    location ~ ^/assets/.*\.php$ {
        deny all;
    }
}
  • root: Обязательно должен указывать на директорию, где лежат файлы сайта (часто это public, web или html). В некоторых фреймворках, например, Yii или Symfony, корневой директорией является подпапка public, чтобы код приложения не лежал в открытом доступе.
  • fastcgi_pass: Указывает адрес, по которому слушает PHP-FPM. Мы рассмотрим настройку этого адреса в PHP-FPM далее. Использование Unix-сокета (unix:/...) предпочтительнее, так как он быстрее TCP-соединения на локальной машине.

тестируем конфигурацию

2.3. Выбор метода связи: Unix Socket vs TCP

В конфигурации PHP-FPM (файл pool.d/www.conf) задается параметр listen, который определяет, где мастер-процесс будет ждать соединения.

  • Unix Socket: listen = /run/php/php8.1-fpm.sock
    • Плюсы: Высокая производительность, так как это обмен данными через файл сокета в обход сетевого стека.
    • Минусы: Сложность с правами доступа. Пользователь, от которого работает Nginx (обычно www-data), должен иметь права на запись в этот сокет. Это настраивается параметрами listen.owner и listen.group в пуле PHP-FPM.
  • TCP Socket: listen = 127.0.0.1:9000
    • Плюсы: Проще с правами доступа, можно перенаправить трафик на другую машину.
    • Минусы: Незначительно медленнее из-за использования сетевого стека.

В приведенном выше блоке location мы использовали Unix-сокет, что является современным стандартом.

Часть 3. Настройка и оптимизация PHP-FPM

3.1. Понимание пулов и параметров pm

PHP-FPM работает с пулами. По умолчанию активен пул www. Настройки пула находятся в файле /etc/php/8.x/fpm/pool.d/www.conf. Основной параметр, влияющий на производительность - pm (process manager). Он может принимать значения:

  • static: Фиксированное количество дочерних процессов (pm.max_children). Подходит для серверов с выделенными ресурсами под PHP и постоянной высокой нагрузкой.
  • dynamic: Динамическое управление. Количество процессов варьируется в заданных пределах. Это стандартный и наиболее гибкий режим.
  • ondemand: Процессы создаются только при поступлении запроса и закрываются после простоя. Экономит память, но может вызывать задержки при всплесках трафика.

Пример настройки динамического пула:

[www]
user = www-data
group = www-data

listen = /run/php/php8.1-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
  • pm.max_children: Максимальное количество процессов, которые могут быть запущены одновременно. Критический параметр, ограниченный оперативной памятью сервера. (Расчет: Память сервера / память на один PHP-процесс).
  • pm.max_requests: Количество запросов, после которого дочерний процесс будет перезапущен. Полезно для предотвращения утечек памяти.

3.2. Оптимизация php.ini

Основной файл конфигурации PHP (php.ini) для FPM находится по пути /etc/php/8.x/fpm/php.ini. Внесите изменения в соответствии с потребностями вашего проекта:

  • Лимиты памяти и времени: Увеличьте, если приложение работает с тяжелыми скриптами или файлами.
    max_execution_time = 300
    memory_limit = 256M
    
  • Загрузка файлов: Если сайт предполагает загрузку изображений или видео, увеличьте лимиты.
    upload_max_filesize = 20M
    post_max_size = 20M
    
    Важно: директиву client_max_body_size также нужно увеличить в конфигурации Nginx.
  • Производительность:
    ; Отключаем fix_pathinfo для безопасности
    cgi.fix_pathinfo = 0
    
    ; Включаем и настраиваем OPcache
    opcache.enable = 1
    opcache.memory_consumption = 128
    opcache.interned_strings_buffer = 8
    opcache.max_accelerated_files = 10000
    opcache.revalidate_freq = 2
    
    OPcache хранит скомпилированный байт-код PHP в памяти, что значительно ускоряет выполнение скриптов.

После любых изменений в php.ini или www.conf необходимо перезапускать PHP-FPM:

sudo systemctl restart php8.1-fpm
php работает

Часть 4. Дополнительная настройка безопасности

4.1. Запрет доступа к чувствительным файлам

Мы уже добавили в конфигурацию Nginx блок location ~ /\., который закрывает доступ к любым файлам, начинающимся с точки (например, .git, .env). Также рекомендуется явно запретить выполнение PHP в директориях с пользовательским контентом, как показано в примере с /assets.

4.2. Права доступа к файлам сайта

Критически важно настроить правильные права, чтобы Nginx мог читать файлы, а PHP-FPM - записывать их (например, для кэша или загрузок). Не стоит запускать процессы от пользователя root. Как правило, и Nginx, и PHP-FPM настроены на работу от пользователя www-data.

# Владельцем файлов должен быть ваш пользователь (для удобства), а группой - www-data
sudo chown -R your_user:www-data /var/www/your_domain

# Стандартные права: 644 для файлов, 755 для директорий
find /var/www/your_domain -type f -exec chmod 644 {} \;
find /var/www/your_domain -type d -exec chmod 755 {} \;

# Для директорий с записью (например, /var/www/your_domain/var/cache) можно дать группе права на запись
# chmod -R 775 /var/www/your_domain/var

4.3. Изоляция через chroot (опционально)

Для максимальной безопасности можно настроить каждый пул PHP-FPM на работу в изолированном окружении (chroot), но это сложная конфигурация, требующая переноса всех необходимых библиотек и устройств внутрь "тюрьмы".

Часть 5. Тестирование и отладка

После завершения настройки необходимо проверить работоспособность связки.

5.1. Проверка конфигурации Nginx

Перед перезагрузкой Nginx всегда проверяйте синтаксис конфигурационных файлов:

sudo nginx -t

Если синтаксис верен, перезагрузите сервер:

sudo systemctl reload nginx

5.2. Создание тестового PHP-файла

Создайте в корневой директории сайта файл info.php:

<?php
phpinfo();
?>

Затем откройте в браузере http://your_domain.com/info.php. Если вы видите полную информацию о конфигурации PHP - значит, связка работает корректно.

5.3. Анализ логов

Если страница не открывается или отображается ошибка 502/504, немедленно обращайтесь к логам:

  • Логи Nginx: /var/log/nginx/error.log
  • Логи PHP-FPM: По умолчанию выводятся в лог пула. Можно настроить в www.conf: php_admin_value[error_log] = /var/log/php-fpm.log и catch_workers_output = yes.

Ошибка 502 Bad Gateway обычно означает, что Nginx не может связаться с PHP-FPM (не запущен FPM, неправильный путь к сокету, неправильные права на сокет).

Ошибка 504 Gateway Time-out означает, что скрипт выполнялся дольше, чем разрешено таймаутом в Nginx (fastcgi_read_timeout) или в PHP-FPM (request_terminate_timeout).

Часть 6. Продвинутая оптимизация производительности

6.1. Тюнинг Nginx

Помимо базовой настройки PHP, можно оптимизировать и сам Nginx в файле nginx.conf:

  • worker_processes: Установите в auto или по количеству ядер CPU.
  • worker_connections: Увеличьте (например, до 4096) для обработки большего числа одновременных соединений.
  • gzip: Включите сжатие передаваемых данных для статических файлов.
  • Кэширование статики: Настройте заголовки expires для изображений, CSS и JS, чтобы браузеры пользователей кэшировали их локально.
# В блоке server или http
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
    expires 30d;
    add_header Cache-Control "public, no-transform";
}

6.2. Настройка буферизации FastCGI

Для ускорения передачи ответов от PHP обратно клиенту, настройте буферизацию:

location ~ \.php$ {
    # ... другие параметры
    fastcgi_buffers 16 16k;
    fastcgi_buffer_size 32k;
    fastcgi_busy_buffers_size 64k;
}

Эти директивы определяют, как Nginx будет читать ответы от PHP-FPM.

6.3. Мониторинг

Используйте встроенный статус PHP-FPM. Для его активации в пуле www.conf раскомментируйте:

pm.status_path = /status

Затем в Nginx создайте location для этого пути, но обязательно ограничьте доступ к нему (по IP или через пароль). Это позволит отслеживать количество активных процессов, очередь и другие метрики в реальном времени.

Сравнение методов обработки PHP

Метод Скорость Потребление памяти Безопасность Гибкость
Apache + mod_php Средняя Высокое Средняя Низкая
Nginx + PHP-FPM (TCP) Высокая Среднее Высокая Высокая
Nginx + PHP-FPM (Unix Socket) Очень высокая Среднее Высокая Высокая
Nginx + FastCGI (внешний) Средняя Низкое Высокая Очень высокая
Apache + FCGID/FPM Средняя Среднее Средняя Средняя

Настройка сервера под связку Nginx и PHP-FPM баланс между безопасностью, производительностью и стабильностью. Мы рассмотрели полный цикл установки, базовой и продвинутой настройки. Ключевые выводы:

  1. Используйте PHP-FPM: Это стандарт для Nginx.
  2. Unix-сокеты предпочтительнее: Они быстрее для локального взаимодействия.
  3. Настройка пулов: Адаптируйте параметры pm под доступную память.
  4. OPcache обязателен: Включайте его для продакшн-серверов.
  5. Логи и мониторинг: Первое средство диагностики проблем.

Данное руководство предоставляет фундамент для развертывания практически любого PHP-приложения, будь то простая "самописная" CRM или сложный фреймворк вроде Symfony или Laravel. Помните, что тонкая настройка всегда должна проводиться с учетом специфики конкретного проекта и его нагрузки.

Еще по теме

Что будем искать? Например,Идея