Обработка PHP-сценариев на сервере Nginx

Раздел: Администрирование веб-серверов -> Настройка веб-сервера Nginx и PHP

Основное решение: настройка 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 секунд на установку соединения.

Обработка HTML и PHP в Nginx - comments

En
Nginx html php (php)