Обработка PHP-сценариев на сервере Nginx
Основное решение: настройка PHP-FPM через FastCGI
Как организовать обработку PHP-файлов на сервере Nginx с помощью PHP-FPM?
Наиболее распространённый и эффективный способ - использование FastCGI-прокси к процессу PHP-FPM. Nginx передаёт запросы к файлам с расширением .php на сокет или TCP-порт, где их обрабатывает PHP-FPM. Такой подход обеспечивает высокую производительность и изоляцию.
server {
listen 80;
server_name example.ru;
root /var/www/html;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}Install nginx php (установка nginx и php (англ.))
Инструкция location ~ \.php$ обрабатывает все запросы, оканчивающиеся на .php. Директива fastcgi_pass указывает адрес сокета PHP-FPM. Параметр SCRIPT_FILENAME формирует полный путь к скрипту на диске.
Типичная ошибка: 502 Bad Gateway. Причины - не запущен PHP-FPM, неверные права доступа к сокету или неправильный путь в fastcgi_pass. Решение - проверить статус службы php-fpm, права на сокет (обычно 666 или 660) и соответствие пути в конфигурации Nginx.
Цель: базовая обработка динамических PHP-страниц. Случаи использования: все проекты на PHP (WordPress, Laravel, Drupal), где необходим единый процессор для скриптов.
Вариант 1: Подключение через TCP-сокет вместо Unix-сокета
Как настроить подключение к PHP-FPM по TCP для распределённой архитектуры?
Иногда удобнее использовать TCP-порт (например, 127.0.0.1:9000) - это позволяет размещать PHP-FPM на другом сервере. В конфигурации меняется значение fastcgi_pass на tcp-адрес.
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
# остальные директивы аналогичны
}Nginx apache php (nginx и apache с php)
Проблема: при использовании TCP возрастает сетевая задержка, а также требуется настройка файрвола. Решение - применять TCP только при необходимости распределения нагрузки между серверами.
Цель: обеспечить возможность раздельного масштабирования веб-сервера и PHP-обработчика.
Вариант 2: Обработка статических файлов без передачи в PHP
Как исключить ненужную обработку статики через PHP-FPM?
Для ускорения отдачи статических ресурсов (изображения, CSS, JS) Nginx должен отдавать их напрямую. Рекомендуется добавить явные правила для статики.
location /static/ {
root /var/www/html;
expires 7d;
}
location ~ \.php$ {
# только php
}Nginx html php (обработка html и php в nginx)
Ошибка: если location для статики не указан, все запросы (даже к статическим файлам) могут попадать в PHP-location, что вызывает ошибки. Решение - использовать точные location или try_files.
Цель: снизить нагрузку на PHP-FPM, ускорить отдачу статики.
Вариант 3: Использование upstream для балансировки нескольких PHP-FPM
Как распределить запросы между несколькими экземплярами PHP-FPM?
При высокой нагрузке можно запустить несколько процессов PHP-FPM и балансировать запросы через upstream в Nginx.
upstream php_backend {
server unix:/var/run/php/php8.2-fpm.sock weight=3;
server 127.0.0.1:9001 backup;
}
server {
...
location ~ \.php$ {
fastcgi_pass php_backend;
...
}
}Nginx index php (настройка index.php в nginx)
Проблема: неверное указание веса или резервного сервера может привести к неравномерной нагрузке. Решение - настроить мониторинг и корректировать веса.
Цель: обеспечить отказоустойчивость и масштабирование.
Вариант 4: Кеширование ответов FastCGI
Как уменьшить время генерации повторяющихся PHP-страниц?
Включение кеширования FastCGI позволяет Nginx сохранять ответы PHP-FPM и отдавать их без повторного обращения к обработчику.
fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=phpcache:100m;
server {
location ~ \.php$ {
fastcgi_cache phpcache;
fastcgi_cache_valid 200 60m;
fastcgi_cache_bypass $http_cache_control;
...
}
}Ошибка: кеширование может привести к отдаче устаревших данных. Решение - использовать строгие настройки сброса кеша или принудительное обновление через заголовки.
Цель: ускорение работы динамических сайтов с редким изменением контента.
Расширенные примеры настройки
Ниже приведены более детальные конфигурации с пояснениями.
Пример 1: Полная конфигурация сервера для WordPress
server {
listen 80;
server_name myblog.ru;
root /var/www/wordpress;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 365d;
add_header Cache-Control "public, immutable";
}
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
error_page 404 /404.html;
}Результат: запросы к /index.php обрабатываются PHP-FPM, статика кешируется на год, а ошибки перенаправляются на статическую страницу.
Пример 2: Использование нескольких версий PHP
# upstream для PHP 7.4
upstream php74 {
server unix:/var/run/php/php7.4-fpm.sock;
}
# upstream для PHP 8.2
upstream php82 {
server unix:/var/run/php/php8.2-fpm.sock;
}
server {
listen 80;
server_name multisite.ru;
location /site1 {
alias /var/www/site1;
location ~ \.php$ {
fastcgi_pass php74;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
}
}
location /site2 {
alias /var/www/site2;
location ~ \.php$ {
fastcgi_pass php82;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
}
}
}Результат: два сайта на одном сервере используют разные версии PHP. Запросы к /site1 обрабатываются PHP 7.4, к /site2 - PHP 8.2.
Пример 3: Ограничение доступа к PHP-файлам по IP
location ~ \.php$ {
allow 192.168.1.0/24;
deny all;
fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
...
}Результат: доступ к PHP-файлам разрешён только из локальной сети 192.168.1.0/24, все остальные получают 403.
Пример 4: Включение error_log для отладки FastCGI
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_intercept_errors on;
error_page 500 502 503 504 /50x.html;
access_log /var/log/nginx/php_access.log;
error_log /var/log/nginx/php_error.log debug;
}Результат: все ошибки FastCGI (502, 503) перехватываются и логируются в отдельный файл с уровнем debug для детального анализа.
Пример 5: Настройка таймаутов для долгих скриптов
location ~ \.php$ {
fastcgi_read_timeout 300;
fastcgi_send_timeout 300;
fastcgi_connect_timeout 30;
...
}Результат: скрипты, выполняющиеся дольше стандартных 60 секунд, не будут прерываться - таймаут увеличен до 5 минут для отправки и чтения, 30 секунд на установку соединения.