Конфигурирование index.php в nginx: варианты и рекомендации
Общие принципы настройки index.php
Директива index в nginx определяет файлы, которые будут обслужены при запросе к директории. Для корректной работы PHP-приложений необходимо не только указать index.php, но и настроить передачу запросов к PHP-файлам на обработчик FastCGI.
Базовое решение: директива index и location для PHP
Как сделать, чтобы при обращении к корню сайта (/) nginx отдавал index.php и корректно обрабатывал его?
В блоке server (или location) указывается:
server {
listen 80;
server_name example.ru;
root /var/www/html;
index index.php; # основной индексный файл
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}Install nginx php (установка nginx и php (англ.))
Пояснение:
- index index.php - при запросе к директории (например,
/) nginx ищет файл index.php в корне ($root). - location ~ \.php$ - все запросы, заканчивающиеся на .php, передаются PHP-FPM через Unix-сокет.
- fastcgi_param SCRIPT_FILENAME - путь к скрипту на сервере.
Если index.php не найден, nginx попробует следующий файл из директивы index (по умолчанию index.html).
Типичная ошибка: 403 Forbidden при обращении к /
Если файл index.php отсутствует, а других индексных файлов нет, nginx вернёт 403. Решение - либо создать index.php, либо добавить fallback в директиву index (например, index index.php index.html).
Ещё одна частая проблема: неверный путь в fastcgi_param SCRIPT_FILENAME. Например, $document_root$fastcgi_script_name против $realpath_root$fastcgi_script_name. Если корень содержит символьную ссылку, может потребоваться $realpath_root.
Вариант 1: Использование try_files для перезаписи на index.php (фреймворки)
Как настроить nginx, чтобы все запросы к несуществующим файлам и директориям передавались на index.php (например, для WordPress, Laravel)?
В этом случае директива index не обязательна, если используется try_files с fallback к index.php:
location / {
try_files $uri $uri/ /index.php$is_args$args;
}Nginx html php (обработка html и php в nginx)
try_files сначала проверяет существование файла ($uri), затем директории ($uri/), и, если ничего не найдено, внутренне перенаправляет на /index.php с исходными аргументами.
При этом нужно обязательно добавить location для .php файлов (как в базовом решении). Этот подход позволяет не указывать index, но если index.php лежит в корне, он всё равно будет вызываться как индексный при доступе к /.
Проблема: бесконечный цикл перенаправлений, если index.php не существует или location для PHP не настроен
Если PHP не обрабатывается, nginx будет пытаться вернуть index.php как статический файл, что вызовет 404 или скачивание. Необходимо убедиться, что location для PHP обрабатывает внутренние редиректы (флаг internal не требуется, если редирект делает try_files).
Вариант 2: Несколько индексных файлов, включая index.php
Как установить приоритет index.php, но оставить fallback на index.html?
Директива index принимает несколько значений, порядок определяет приоритет:
index index.php index.html index.htm;Nginx index php (настройка index.php в nginx)
При запросе к директории nginx сначала ищет index.php, затем index.html, затем index.htm. Это полезно, если PHP-скрипт может отсутствовать и нужно показать статическую страницу.
Особенность: nginx не разрешает внутренний редирект между разными типами файлов
Если index.php существует, но обработка PHP настроена неправильно, nginx может отдать его как статику (например, скачать). Поэтому все .php файлы должны обязательно попадать в location для PHP.
Вариант 3: index.php в поддиректории
Как сделать index.php внутри подпапки (например, /app/index.php) основным для всего сайта?
Если корень сайта /var/www, а index.php лежит в /var/www/app/index.php, то директива index меняется на:
root /var/www;
index app/index.php;Nginx apache php (nginx и apache с php)
Теперь при запросе к / nginx будет пытаться найти файл /var/www/app/index.php. Если нужно, чтобы также обрабатывались другие PHP-файлы, location для PHP должен охватывать всю подпапку: location ~ ^/app/.+\.php$.
Проблема: try_files с относительным путём может не сработать
Если используется try_files $uri $uri/ /app/index.php, то путь к fallback должен быть относительным корня (не обязательно начинаться с /).
Вариант 4: index.php с параметрами (строка запроса)
Можно ли передать параметры при вызове index.php?
Директива index не поддерживает параметры в строке. Для передачи параметров используется try_files с фиксацией аргументов, например:
location / {
try_files $uri $uri/ /index.php?$args;
}установка nginx php (установка nginx и php)
Здесь $args - исходные query-параметры запроса. Если нужно добавить свои параметры, их можно включить в URL: /index.php?custom=1&$args.
А если index.php должна передаваться управляющая переменная?
Можно задать в директиве index только имя файла, а всю логику перенаправления оставить на rewrite внутри location.
Вариант 5: Использование сокета или TCP для fastcgi_pass
Как подключить PHP-FPM, работающий на TCP-порту?
В location для PHP можно указать:
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
fastcgi_index index.php; - устанавливает индексный файл для $fastcgi_script_name, если его нет в запросе (полезно, когда index.php обрабатывается напрямую через FastCGI, например, при вызове скрипта через PHP-FPM без nginx). В обычных запросах nginx уже передаёт правильное имя файла, но эта директива может пригодиться при внутренних редиректах.
Ошибка: соединение с PHP-FPM по TCP не удаётся
Проверить, работает ли PHP-FPM на порту 9000, можно командой netstat -tulpn | grep 9000. Если процесс не слушает, исправить настройки пула PHP (listen = 127.0.0.1:9000).
Расширенные примеры настройки index.php
Пример 1: Комбинированная конфигурация с двумя корнями и index.php
server {
listen 80;
server_name site.ru;
# Основной корень для статики
root /var/www/site/public;
# Если запрошенная директория содержит index.php – отдаём его через PHP
index index.php;
# Все PHP-файлы обрабатываем через сокет
location ~ \.php$ {
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
}
# Для админ-панели отдельный корень и index.php
location /admin {
alias /var/www/admin/public;
try_files $uri $uri/ /admin/index.php?$args;
location ~ \.php$ {
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
fastcgi_param SCRIPT_FILENAME $request_filename;
include fastcgi_params;
}
}
}
Результат: при запросе /admin/ nginx ищет /var/www/admin/public/index.php (благодаря try_files внутри location /admin). alias и try_files в паре требуют внимания к пути fallback.
Пример 2: Использование map для динамического выбора index-файла
map $uri $index_file {
~^/old/ index.php;
~^/new/ index.html;
default index.php;
}
server {
root /var/www;
index $index_file;
# ...
}
Здесь директива index принимает переменную. Если запрос начинается с /old/, индексом будет index.php; если с /new/ - index.html. Обратите внимание: такое использование менее производительно, но гибко.
Пример 3: Настройка index.php в конфигурации с HTTPS и фильтрацией запросов
server {
listen 443 ssl http2;
server_name example.ru;
ssl_certificate /etc/ssl/certs/example.crt;
ssl_certificate_key /etc/ssl/private/example.key;
root /srv/example;
index index.php;
# Запрет доступа к скрытым файлам (включая index.php в особых папках)
location ~ /\. {
deny all;
return 404;
}
# Основной location для PHP
location ~ \.php$ {
# Ограничить размер загружаемых файлов
client_max_body_size 10M;
try_files $uri =404;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
# Передача дополнительных параметров в PHP-скрипт
fastcgi_param APPLICATION_ENV production;
}
# Статика отдаётся напрямую с кэшированием
location ~* \.(css|js|png|jpg)$ {
expires 30d;
access_log off;
}
}
Результат: при обращении к / nginx ищет /srv/example/index.php, и если файл найден, передаёт его PHP-FPM по TCP. Дополнительно настроена защита от доступа к .htaccess и подобным файлам.
Пример 4: Обработка ошибок с перенаправлением на index.php (кастомная страница 404)
server {
root /var/www/site;
index index.php;
error_page 404 /index.php?error=404;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
При возникновении 404 nginx выполняет внутренний редирект на /index.php?error=404. Сам index.php должен обрабатывать параметр error и отдавать соответствующий контент.
Пример 5: Отладка ошибок с index.php через логирование
http {
log_format debug '$remote_addr $uri $status $request_time $upstream_response_time';
access_log /var/log/nginx/debug.log debug;
}
server {
index index.php;
root /app;
# ...
}
Проверка в логах: если запрос / возвращает 404, а должен 200, смотреть строку с $uri - возможно, nginx ищет не тот файл или не проходит FastCGI.
Пример 6: Нестандартное имя индексного файла (app.php)
server {
index app.php;
location / {
try_files $uri $uri/ /app.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
Здесь вместо index.php используется app.php. Все правила перенаправления и обработки PHP остаются теми же.