位置块传递到不同的 php-fpm sock

位置块传递到不同的 php-fpm sock

有两个主机,每个主机都有一个 PHP-FPM 池 - one.com 和 two.com。我希望 one.com/two 能够通过并使用 two 的池显示 two.com,但我似乎遇到了困难。

通过aliastry_files,我已成功从通过one.com/two/path/to/asset.ext 提供的two.com文件中获取静态资产,但PHP请求例如one.com/two/index.php(以及对two文件中不存在的文件的请求)似乎回退到最后一条规则并显示one.com的应用程序404页面。

这是 one.com 的位置配置:

location / {
    try_files $uri $uri/ /index.php$is_args$args;
}

location ~* ^/two$ {
        return 301 /two/;
}

location /two/ {
        alias /srv/two.com/public/;
        try_files $uri $uri/ /two/index.php$is_args$args;
}

location ~* ^/two/(.+\.php)$ {
        alias /srv/two.com/public/$1;
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/7.1-two.com.sock;
}

location ~* \.php$ {
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/var/run/php/7.1-one.com.sock;
}

snippets/fastcgi-php.conf

# regex to split $uri to $fastcgi_script_name and $fastcgi_path
fastcgi_split_path_info ^(.+\.php)(/.+)$;

# Check that the PHP script exists before passing it
try_files $fastcgi_script_name =404;

# Bypass the fact that try_files resets $fastcgi_path_info
# see: http://trac.nginx.org/nginx/ticket/321
set $path_info $fastcgi_path_info;
fastcgi_param PATH_INFO $path_info;

fastcgi_index index.php;
include snippets/fastcgi_params.conf;

$1因为别名似乎是正确的 - 我用return 302 /$1 which would redirect the client to the expected path (e.g./two/foo.php ->/foo.php 替换了该块)

此外,如果我放置deny all;最后两个位置块中的任何一个,它会阻止所有受影响的请求(/two/*.php,/two/path/to/nonexistent.file)

就像它没有在第一个 fastcgi 传递位置块处停止一样 - 我是否遗漏了应该告诉它停止的东西?

-

编辑:添加break;没有停止,并且尝试通过在每个位置块中添加标题来调试只显示最后一个通用 php 块中存在的标题。

-

编辑2:

事实证明,fastcgi_split_path_info需要进行更改才能考虑目录前缀。

因此,我撕掉了代码片段文件并在位置块内对其进行了一些修改:

location ^~ /two {
        alias /data/srv/nginx/two.com/public/;
        try_files $uri $uri/ /two/index.php$is_args$args;

        location ~* ^\/two.+\.php$ { # have also tried with just \.php$
            alias /srv/two.com/public/$1;

            fastcgi_split_path_info ^/two(.+\.php)().*$; # the second group is deliberately empty.

            try_files $fastcgi_script_name =404;

            fastcgi_param PATH_INFO $path_info;

            fastcgi_index index.php;
            include snippets/fastcgi_params.conf;

            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

            fastcgi_pass unix:/var/run/php/7.1-two.com.sock;
        }
}

这似乎使位置块正常工作,除非我遍历更深的一个级别,例如/two/account- 再次显示one.com 的 404 页面。

我在外部位置放置了一个拒绝,这会阻止请求,但在内部位置放置一个拒绝却不会阻止请求。出于某种原因,它决定使用原始代码中的最后一个正则表达式位置。

答案1

所以我找到了问题和一个不太好的解决方案。

根据 nginx 文档,存在一个已知错误,当使用try_filesalias同一个上下文中(不会被修复)。

nginx bugtracker 对该错误进行了讨论包括案例和实际发生的情况。

因此,我最终需要做的是更改我的配置如下:

首先,需要从alias行中删除尾随的斜杠,因为try_files斜杠会在其自身上添加。

其次,try_files第一个块中的 需要在请求名称前加上两个前缀,而不是/two/index.php/two/two/index.php因为别名会在确定下一个位置块之前剪掉第一部分)。

最后,对于 PHP,我需要调整REQUEST_URIso 而不是/two/index.php将其作为 传递/index.php

我在主 nginx 配置中创建了一个变量映射,如下所示:

http {

    # ...

    map $request_uri $prefixless_request_uri {
        "~^/[^/]+(?P<path>.*)$" $path;
    }

然后在我调用fastcgi_pass覆盖传递的值之前引用它。

fastcgi_param REQUEST_URI $prefixless_request_uri;

相关内容