Nginx: конфигурация для WordPress с PHP-FPM
Официальная конфигурация Nginx для WordPress с PHP-FPM, поддержкой pretty permalinks, кеширования и безопасности. Основано на документации WordPress.org.
Как использовать
- Скопируйте блок server, замените server_name, root и пути к логам и SSL-сертификатам.
- Убедитесь, что try_files для location / содержит /index.php?$args для pretty permalinks.
- Запретите выполнение PHP в uploads: location ~* /(?:uploads|files)/.*\.php$ { deny all; }. Проверка: nginx -t; systemctl reload nginx.
Под WordPress на Nginx запросы к PHP отдаёт PHP-FPM через fastcgi; для «человекопонятных» URL (pretty permalinks) все запросы должны уходить в index.php с query string. Без правильного try_files страницы постов и рубрик отдают 404; без запрета выполнения PHP в uploads загруженный вредоносный .php может выполниться. Проблема: типовой конфиг под Apache не подходит — Nginx не читает .htaccess. Симптомы: 404 на страницах с permalinks, выполнение PHP в wp-content/uploads, потеря GET-параметров. Ниже — базовая конфигурация и вариант с HTTPS по документации WordPress.org и Nginx WordPress Recipe; проверка и типичные ошибки.
Решение
Конфигурация Nginx для WordPress с PHP-FPM: pretty permalinks, защита скрытых файлов и uploads, кеш статики.
Базовая конфигурация (HTTP)
server {
listen 80;
server_name example.com www.example.com;
root /var/www/wordpress;
index index.php index.html;
access_log /var/log/nginx/wordpress-access.log;
error_log /var/log/nginx/wordpress-error.log;
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location ~ /\. {
deny all;
}
location ~* /(?:uploads|files)/.*\.php$ {
deny all;
}
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_index index.php;
fastcgi_intercept_errors on;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires max;
log_not_found off;
}
}
С поддержкой HTTPS
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com www.example.com;
root /var/www/wordpress;
index index.php index.html;
ssl_certificate /etc/ssl/certs/example.com.crt;
ssl_certificate_key /etc/ssl/private/example.com.key;
access_log /var/log/nginx/wordpress-access.log;
error_log /var/log/nginx/wordpress-error.log;
location = /favicon.ico { log_not_found off; access_log off; }
location = /robots.txt { allow all; log_not_found off; access_log off; }
location ~ /\. { deny all; }
location ~* /(?:uploads|files)/.*\.php$ { deny all; }
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_index index.php;
fastcgi_intercept_errors on;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires max;
log_not_found off;
}
}
Важно: для pretty permalinks обязателен try_files ... /index.php?$args (с ?$args). В php.ini должно быть cgi.fix_pathinfo = 0. Nginx не использует .htaccess — всё в конфиге сервера.
Проверка
- Синтаксис и перезагрузка:
sudo nginx -t
sudo systemctl reload nginx
-
Главная и страница с permalink — откройте главную и любую страницу/запись с «человекопонятным» URL. Не должно быть 404. Если 404 — проверьте, что в location / стоит именно
/index.php?$args. -
Запрет PHP в uploads — положите в wp-content/uploads тестовый файл test.php с содержимым
<?php echo 'exec'; ?>. Запрос кhttps://example.com/wp-content/uploads/2026/02/test.phpдолжен вернуть 403 (deny all), а не выполнить код. -
Путь к PHP-FPM — сокет в
fastcgi_passдолжен совпадать с настройками PHP-FPM (часто/run/php/php8.2-fpm.sockили127.0.0.1:9000). При неверном пути nginx отдаёт 502.
Типичные ошибки
- Нет
?$argsв try_files — без него query string теряется, WordPress не получает REQUEST_URI и отдаёт 404 на страницах с permalinks. Всегда используйте/index.php?$args. - cgi.fix_pathinfo = 1 в php.ini — при этом PHP может выполнить другой файл по пути; рекомендуется 0. Проверьте:
php -i | grep fix_pathinfo. - Выполнение PHP в uploads — без location с deny all для
.*\.php$в uploads загруженный скрипт выполнится. Обязательно запрещайте выполнение в каталогах загрузок. - root указывает не на каталог WordPress — root должен быть каталог, в котором лежат index.php, wp-config.php и т.д. (при структуре с public — корень сайта, где доступен index.php).
Где применять
- Prod / dev: сервер с Nginx и PHP-FPM под один или несколько сайтов WordPress. Логи можно вынести в каталог сайта (структура каталогов).
- SSL: подставьте пути к сертификатам (или используйте Let’s Encrypt по аналогии для своего пути).
Связанные сниппеты: Структура каталогов для сайтов, Nginx и SSL Let’s Encrypt (BitrixVM), Анализ логов nginx.