Главная страница загружается, но все постоянные ссылки возвращают 404 при использовании nginx и PHP-FPM
Я пытаюсь решить странную проблему с конфигурацией nginx, которая перестала работать после обновления Debian из backports.
Главная страница моего блога (http://blog.balaji-dutt.name/) работает нормально, но при переходе по любой постоянной ссылке (Пример 1, Пример 2) возникает ошибка 404 от nginx.
Вот моя конфигурация, которая сейчас практически стандартна из Codex:
server {
listen 80;
server_name blog.balaji-dutt.name;
error_log /var/log/nginx/blog-error.log;
access_log /var/log/nginx/blog-access.log combined;
## Ваш единственный путь к корню.
root /var/www/wordpress;
## Это должно быть в http блоке, и если там есть, здесь не нужно.
index index.php;
#Gzip
include /etc/nginx/sites-available/gzip.conf;
location / {
# Это хорошо, потому что статический контент не требует PHP.
# Включаем "?$args", чтобы нелогичные постоянные ссылки не ломались при использовании строки запроса
try_files $uri $uri/ /index.php?$args;
}
# запрещаем доступ к .htaccess файлам, если корень Apache
# совпадает с корнем nginx
#
location ~ /\.ht {
deny all;
access_log off;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include fastcgi_params;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
#fastcgi_intercept_errors on;
fastcgi_pass 127.0.0.1:9010;
}
}
Вот что я вижу в логе ошибок nginx при попытке доступа к постоянной ссылке (http://blog.balaji-dutt.name/about/):
2014/10/19 03:35:09 [error] 21698#0: *76739 "/var/www/wordpress/about/index.php" is not found (2: No such file or directory), client: 174.36.241.151, server: blog.balaji-dutt.name, request: "GET /about/ HTTP/1.1", host: "blog.balaji-dutt.name", referrer: "http://blog.balaji-dutt.name/"
Похоже, что nginx не читает директиву location для .php файлов, но я не могу понять, почему это происходит. Любые предложения или помощь очень приветствуются!
Обновление 1 - 20 октября 2014
Содержимое корневой директории nginx:
# ls -la /var/www/wordpress
total 256
drwxr-xr-x 5 blog www-data 4096 Sep 28 03:09 .
drwxr-xr-x 8 www-data www-data 4096 Jan 15 2014 ..
-rw-r--r-- 1 blog www-data 418 Sep 25 2013 index.php
-rw-r--r-- 1 blog www-data 19930 May 16 22:23 license.txt
-rw-r--r-- 1 blog www-data 1764 Oct 5 01:17 nginx.conf
-rw-r--r-- 1 blog www-data 7192 Sep 28 03:09 readme.html
-rw-r--r-- 1 blog www-data 55174 Mar 27 2014 sitemap.backup.xml
-rw-r--r-- 1 blog www-data 7125 Mar 27 2014 sitemap.backup.xml.gz
-rw-r--r-- 1 blog www-data 4951 Sep 28 03:09 wp-activate.php
drwxr-xr-x 9 blog www-data 4096 Dec 12 2013 wp-admin
-rw-r--r-- 1 blog www-data 271 Jan 8 2012 wp-blog-header.php
-rw-r--r-- 1 blog www-data 4946 Sep 28 03:09 wp-comments-post.php
-rw-r--r-- 1 blog www-data 2746 Sep 28 03:09 wp-config-sample.php
-rw-r--r-- 1 blog www-data 237 Dec 22 2013 wp-config.php
drwxr-x--- 9 blog www-data 4096 Sep 28 03:09 wp-content
-rw-r--r-- 1 blog www-data 2956 Sep 28 03:09 wp-cron.php
drwxr-xr-x 12 blog www-data 4096 Sep 28 03:09 wp-includes
-rw-r--r-- 1 blog www-data 2380 Oct 24 2013 wp-links-opml.php
-rw-r--r-- 1 blog www-data 2714 Sep 28 03:09 wp-load.php
-rw-r--r-- 1 blog www-data 33043 Sep 28 03:09 wp-login.php
-rw-r--r-- 1 blog www-data 8252 Sep 28 03:09 wp-mail.php
-rw-r--r-- 1 blog www-data 11115 Sep 28 03:09 wp-settings.php
-rw-r--r-- 1 blog www-data 26256 Sep 28 03:09 wp-signup.php
-rw-r--r-- 1 blog www-data 4026 Oct 24 2013 wp-trackback.php
-rw-r--r-- 1 blog www-data 3032 May 16 22:23 xmlrpc.php
При попытке доступа к URL (http://blog.balaji-dutt.name/2013/481-nginx-apache-w3-total-cache-a-bad-combination/) в логе nginx появляется следующее:
*14 "/var/www/wordpress/2013/481-nginx-apache-w3-total-cache-a-bad-combination/index.php" is not found (2: No such file or directory), client: 174.36.241.151, server: blog.balaji-dutt.name, request: "GET /2013/481-nginx-apache-w3-total-cache-a-bad-combination/ HTTP/1.1", host: "blog.balaji-dutt.name", referrer: "http://blog.balaji-dutt.name/"
Путь в логе ошибок сбивает с толку, потому что часть после /var/www/wordpress/
- это фактически постоянная ссылка, и я не понимаю, почему она добавляется к запросу.
Обновление 2 - 25 октября 2014 [РЕШЕНО]
Оказалось, что конфигурационный файл nginx, созданный W3 Total Cache для Disk Enhanced кэширования, ломает постоянные ссылки. Но так как файл читается только при перезагрузке nginx, сайт будет работать до тех пор, пока вы не перезагрузите/перезапустите nginx. Подробный ответ и рабочая конфигурация опубликованы в этом ответе.

Оказывается, конфигурация nginx, которую W3 Total Cache вставляет при включённом режиме Disk Enhanced, ломает постоянные ссылки, но только если перезапустить nginx после того, как W3 Total Cache добавит конфигурацию для режима Disk Enhanced.
Основываясь на предложении birgire, я отключил все плагины и проверил сайт, который начал работать корректно. Затем я включил W3 Total Cache и сюрприз! сайт продолжал работать правильно. Он работал корректно до тех пор, пока я не перезапустил nginx, после чего файл nginx.conf, созданный W3 Total Cache, был загружен, и сайт перестал работать. Причиной такого поведения является следующая строка:
if ($w3tc_rewrite = 1) {
rewrite .* "/wp-content/cache/page_enhanced/$http_host/$request_uri/_index$w3tc_rewrite$w3tc_ext" last;
}
При перезапуске nginx эта строка загружается, и все URL перенаправляются на закэшированные HTML-файлы в wp-content/cache/page_enhanced
. Однако после перезапуска HTML-файлы очищаются, и ссылки возвращают 404 ошибку. Решение, которое я нашёл, заключалось в том, чтобы сначала изменить разрешения на файл конфигурации nginx, в который обычно записывает W3 Total Cache, чтобы он не мог быть перезаписан. Затем я изменил конфигурацию следующим образом:
location / {
rewrite ^(.*\/)?w3tc_rewrite_test/?$ $1?w3tc_rewrite_test=1 last;
if ($w3tc_rewrite = 1) {
rewrite .* "/wp-content/cache/page_enhanced/$http_host/$request_uri/_index$w3tc_rewrite$w3tc_ext" last;
}
try_files $uri $uri/ /index.php?$args;
}
Эта конфигурация делает несколько вещей — оригинальная строка rewrite обёрнута в блок location, так что даже если HTML-файл не найден, система возвращается к стандартной модели рендеринга через index.php. Кроме того, строка w3tc_rewrite_test
добавлена для устранения ошибки в админ-панели. Я делаю это в отдельном файле, чтобы централизовать конфигурацию W3 TC, поэтому в моём сайте есть две директивы location \
.
Дополнительно выяснилось, что конфигурация nginx для модуля минификации W3 Total Cache также не работает. Вот рабочая конфигурация1:
#Test Rewrites
location ~ ^/wp-content/cache/minify/[^/]+/(w3tc.*)$ {
try_files $uri /wp-content/plugins/w3-total-cache/pub/minify.php?w3tc_rewrite_test=$1;
}
#End Test Rewrites
# BEGIN W3TC Minify core
set $w3tc_enc "";
location ~ ^/wp-content/cache/minify/(.+/[X]+\.css)$ {
try_files $uri /wp-content/plugins/w3-total-cache/pub/minify.php?test_file=$1;
}
location ~ ^/wp-content/cache/minify/(.+\.(css|js))$ {
try_files $uri /wp-content/plugins/w3-total-cache/pub/minify.php?file=$1;
}
# END W3TC Minify core
Так как большая часть информации о Wordpress/W3 Total Cache зависит от версии, вот данные о версиях для приведённой конфигурации: W3 Total Cache v0.9.4 / Wordpress 4.0 / nginx 1.6.2-2~bpo70+1
1 https://rtcamp.com/wordpress-nginx/tutorials/single-site/w3-total-cache/

Просто примите свой ответ как правильный. Смотрите "Могу ли я назначить награду за свой собственный ответ?" http://meta.stackexchange.com/questions/16065/how-does-the-bounty-system-work

Вы можете исправить это без изменения конфигурационного файла w3, просто изменив правило location / rewrite на try_files $uri $uri/ /index.php$is_args$args;
. Ссылка: http://wordpress.stackexchange.com/questions/98271/enable-minify-in-w3total-cache-using-nginx
