过去两周我一直在研究这个问题,但不知为何,我似乎无法让 nginx 的 try_files 与我的 wordpress 永久链接一起工作。我希望有人能告诉我哪里出错了,也希望告诉我我的配置是否出了什么重大错误(我是 nginx 新手……但正在学习 :))。
这是我的配置文件
nginx.conf
user www-data;
worker_processes 4;
pid /var/run/nginx.pid;
events {
worker_connections 768;
# multi_accept on;
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# Logging Settings
##
# Defines the cache log format, cache log location
# and the main access log location.
log_format cache '***$time_local '
'$upstream_cache_status '
'Cache-Control: $upstream_http_cache_control '
'Expires: $upstream_http_expires '
'$host '
'"$request" ($status) '
'"$http_user_agent" '
;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
我的域名.com.conf
server {
listen 123.456.78.901:80; # IP goes here.
server_name www.mydomain.com mydomain.com;
#root /var/www/mydomain.com/prod;
index index.php;
## mydomain.com -> www.mydomain.com (301 - Permanent)
if ($host !~* ^(www|dev))
{
rewrite ^/(.*)$ $scheme://www.$host/$1 permanent;
}
# Add trailing slash to */wp-admin requests.
rewrite /wp-admin$ $scheme://$host$uri/ permanent;
# All media (including uploaded) is under wp-content/ so
# instead of caching the response from apache, we're just
# going to use nginx to serve directly from there.
location ~* ^/(wp-content|wp-includes)/(.*)\.(jpg|png|gif|jpeg|css|js|m$
root /var/www/mydomain.com/prod;
}
# Don't cache these pages.
location ~* ^/(wp-admin|wp-login.php)
{
proxy_pass http://backend;
}
location / {
if ($http_cookie ~* "wordpress_logged_in_[^=]*=([^%]+)%7C") {
set $do_not_cache 1;
}
proxy_cache_key "$scheme://$host$request_uri $do_not_cache";
proxy_cache main;
proxy_pass http://backend;
proxy_cache_valid 30m; # 200, 301 and 302 will be cached.
# Fallback to stale cache on certain errors.
# 503 is deliberately missing, if we're down for maintenance
# we want the page to display.
#try_files $uri $uri/ /index.php?q=$uri$args;
#try_files $uri =404;
proxy_cache_use_stale error
timeout
invalid_header
http_500
http_502
http_504
http_404;
}
# Cache purge URL - works in tandem with WP plugin.
# location ~ /purge(/.*) {
# proxy_cache_purge main "$scheme://$host$1";
# }
# No access to .htaccess files.
location ~ /\.ht {
deny all;
}
} # End server
gzip配置文件
# Gzip Configuration.
gzip on;
gzip_disable msie6;
gzip_static on;
gzip_comp_level 4;
gzip_proxied any;
gzip_types text/plain
text/css
application/x-javascript
text/xml
application/xml
application/xml+rss
text/javascript;
代理配置文件
# Set proxy headers for the passthrough
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_max_temp_file_size 0;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
add_header X-Cache-Status $upstream_cache_status;
后端配置文件
upstream backend {
# Defines backends.
# Extracting here makes it easier to load balance
# in the future. Needs to be specific IP as Plesk
# doesn't have Apache listening on localhost.
ip_hash;
server 127.0.0.1:8001; # IP goes here.
}
缓存配置文件
# Proxy cache and temp configuration.
proxy_cache_path /var/www/nginx_cache levels=1:2
keys_zone=main:10m
max_size=1g inactive=30m;
proxy_temp_path /var/www/nginx_temp;
proxy_cache_key "$scheme://$host$request_uri";
proxy_redirect off;
# Cache different return codes for different lengths of time
# We cached normal pages for 10 minutes
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
我尝试了 mydomain 配置文件中位置 \ 处的两个注释掉的 try_files。我在错误日志中发现的这个错误可以在下面找到。
...rewrite or internal redirection cycle while internally redirecting to "/index.php"
提前致谢
答案1
这看上去是一个非常复杂的设置。
我的第一个想法是建议您完全摆脱 Apache;nginx + php-fpm 完全能够为您的 WordPress 博客提供服务,并且您会发现大多数 WordPress nginx 规则都希望 nginx 用作原始服务器,而不是 Apache 的反向代理。
现在,继续表演……
您不能在向上游传递请求的try_files
同一个location
块中使用。它会被忽略,因为无论如何一切都会转到代理。如果您想让它工作,我建议使用命名位置。类似这样(我脑海中浮现的):
root /var/www/whatever;
location @apache {
# proxy directives here
}
location / {
try_files $uri $uri/ @apache;
}
这里的想法是,你让 nginx 首先处理 nginx 可以处理的东西,然后将其他所有东西传递到上游。
当然,添加您需要的任何附加指令,但想法是从简单开始,确保基本内容可以正常工作,然后再添加内容来重写静态页面请求、cookie 等。
答案2
正如 Michael Hampton 所说,您的设置相当复杂,最好先保持简单并先让其正常工作。这是我为 nginx 进行的基本 WordPress 设置(适用于漂亮的永久链接):
root /var/www/mydomain.com/prod;
index index.php;
location / {
# This is cool because no PHP is called for static content
# The key thing here is passing the $args to index.php
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
# Zero-day exploit defense
# http://forum.nginx.org/read.php?2,88845,page=3
# Won't work properly (404 error) if the file is not stored on this
#server, which is entirely possible with php-fpm/php-fcgi.
# Comment the 'try_files' line out if you set up php-fpm/php-fcgi on
#another machine. And then cross your fingers that you won't get hacked.
try_files $uri =404;
# For caching advice, see Mark Jaquith's superb post here:
# http://markjaquith.wordpress.com/2012/05/15/how-i-built-have-baby-need-stuff/
# To do some super-fancy rate limiting for the backend PHP requests,
# declare the following limit_req_zone in the http {} block of your nginx.conf e.g.
# limit_req_zone $binary_remote_addr zone=appserver:1m rate=2r/s;
# Then uncomment the below limit_req_zone line
## Set the request zone to limit backend DoSsing
# limit_req zone=appserver burst=6;
include /etc/nginx/proxy.conf;
proxy_pass http://backend;
}
就是这样 — 简单又好用。您不再需要从旧配置中执行以下任何操作:(try_files 将使 nginx 尝试直接为其提供服务,然后尝试下一个参数选项,然后是下一个,等等。)
# # Add trailing slash to */wp-admin requests.
# rewrite /wp-admin$ $scheme://$host$uri/ permanent;
# # All media (including uploaded) is under wp-content/ so
# # instead of caching the response from apache, we're just
# # going to use nginx to serve directly from there.
# location ~* ^/(wp-content|wp-includes)/(.*)\.(jpg|png|gif|jpeg|css|js|m$
# root /var/www/mydomain.com/prod;
# }
# # Don't cache these pages.
# location ~* ^/(wp-admin|wp-login.php)
# {
# proxy_pass http://backend;
# }
为了便于测试,请打开终端,通过 SSH 进入您的服务器并运行tail -f /var/log/nginx/*.log
(或存储日志的任何地方),然后观察错误。更改配置后,不要忘记重新启动或重新加载服务器!
此外,根据您所运行的 nginx 版本和操作系统(我从您的 /var/www/ 路径猜测是 Debian 或 Ubuntu),您可能能够运行该程序来/etc/init.d/nginx configtest
测试您的配置文件并报告有关任何错误的有用错误消息 - 这将使生活变得轻松很多。
完成上述操作并测试后,这里有一些很酷的技巧,例如为上传的图像添加过期和缓存标头;IP 限制、速率限制以及管理员访问和登录尝试的额外日志记录;等等:
location ~ ^/wp-content/uploads/.+\.(jpe?g|gif|png|ico|bmp)$ {
# set a expires to max as per http://developer.yahoo.com/performance/rules.html/#expires
expires max;
add_header Cache-Control public;
}
# Make sure you avoid the static cache when logging in or doing admin
location /wp-admin {
# Restrict by IP for extra security (I'd also highly recommend the Login Lockdown plugin or the Duo Two-Factor Authentication plugin)
# allow 81.128.0.0/11; # BT Central Plus
# allow 86.128.0.0/10; # BT Central Plus
# deny all;
access_log /var/log/nginx/wp-admin.log;
error_log /var/log/nginx/wp-admin.error.log error;
include /etc/nginx/proxy.conf;
proxy_pass http://backend;
}
# Make sure you avoid the static cache when logging in or doing admin
location = /wp-login.php {
# Restrict by IP for extra security
# allow 81.128.0.0/11; # BT Central Plus
# allow 86.128.0.0/10; # BT Central Plus
# deny all;
# Declare the zone in the http {} block of your nginx.conf e.g.
# limit_req_zone $binary_remote_addr zone=appserver:1m rate=2r/s;
# Then uncomment the below line to limit hits to wp-login to 2 per second (plus a burst of 2 using the leaky bucket model)
# limit_req zone=appserver burst=2 nodelay;
access_log /var/log/nginx/login-attempts.log;
include /etc/nginx/proxy.conf;
proxy_pass http://backend;
}
答案3
我使用 Nginx 和 PHP-FPM 运行许多 WordPress 网站。对于我来说,此配置似乎适用于配置文件目录...(出于安全考虑删除了具体细节)。
server {
listen 123.123.123.123:80;
server_name example.com;
client_max_body_size 128m;
root /app/<user>/www;
index index.html index.htm index.php;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
fastcgi_pass unix:/tmp/php-fpm.example.com.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}