nginx try_files,proxy_pass和上游

时间:2016-04-08 22:48:00

标签: php wordpress nginx

我正在建立一个码头测试平台'对于PHP应用程序 - 特别是(目前)WordPress。我使用PHPFarm在不同的端口上提供不同版本的PHP。在前面使用nginx,我已经有很多工作了。 (https://github.com/richardtape/testit是主要的回购)

我现在面临的一个重大问题是获得WordPress"非常永久链接"上班。在标准的nginx设置中,它只是像

这样的情况
location / {
    index index.php index.html index.htm;
    try_files $uri $uri/ /index.php?$args;
}

但是为了能够从主机获得不错的网址,并且为了拥有一个代码库,我使用了以下几行:

server {
    listen 80;
    index index.php index.html index.htm;
    server_name 52.spaces.dev;

    location / {

        proxy_pass http://phpfarm_52;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $remote_addr;
    }
    root /var/www;
}

upstream phpfarm_52{
    server phpfarm:8052;
}

现在,这是有效的。 (对于PHP 5.3,5.4,5.5,5.6和7,还有5个类似的规则)主页加载来自主机的每个不同的server_names(如果你在每个上输出PHP版本,你可以看到你正在获得不同的PHP版本。)

然而,第二个我切换到内部' url(或任何非root,即http://52.spaces.dev/about/),我得到404.我已经尝试了类似的东西

location / {
    try_files $uri $uri/ /index.php?$args
}

location ~ \.php$ {
    proxy_pass http://phpfarm_52;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $remote_addr;
}

我获得了一个重定向循环,取决于我尝试过的几种不同方式,或者只是一系列301重定向,页面从未加载或出现错误,例如

nginx_1      | 2016/04/08 20:31:29 [error] 5#5: *4 rewrite or internal redirection cycle while processing "/index.php", client: 192.168.99.1, server: 52.spaces.dev, request: "GET /favicon.ico HTTP/1.1", host: "52.spaces.dev", referrer: "http://52.spaces.dev/"

我被困住了。我对nginx配置也很陌生(这可能是显而易见的)所以我可能会做一些完全错误和/或愚蠢的事情。有什么建议吗?

1 个答案:

答案 0 :(得分:9)

您在问题中使用重定向循环遇到的问题是,基本上每个请求,即使是静态文件,也会尝试通过index.php?$ args块进行路由。

我在这里看到了两种可能的解决方案。首先,如果您愿意使用单个nginx实例实现nginx设置,请查看以下主题:NGINX try_files with multiple named locations和此博客文章http://linuxplayer.org/2013/06/nginx-try-files-on-multiple-named-location-or-server

需要发生什么,是否需要首先测试资源是否存在于上游(即,不返回404)。如果是,那么你按原样服务。如果没有,那么你将调用重写块,它试图将它作为index.php的参数。所以你最终会得到这样的东西(抱歉,我真的没有机会对此进行测试,但希望它能给出一个想法):

location / {
    try_files $uri $uri/ @phpproxy;
}

location @phpproxy {
    proxy_pass http://phpfarm_52;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_intercept_errors on;
    recursive_error_pages on;
    error_page 404 = @rewrite_proxy;
}

location @rewrite_proxy {
    rewrite ^/(.*)$ /index.php?$1 break;
    proxy_pass http://phpfarm_52;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $remote_addr;
}

第二个解决方案(我个人更喜欢)是使用自己的nginx在每个上游。然后,面向所有其他人的顶级nginx将具有更简洁的proxy_pass(+可能是一些静态内容)的更清晰的结构,而这就是它。它还会减少往返请求,因为您不需要解决来自上游的404。