Назад | Перейти на главную страницу

Блок местоположения передается на другой носок php-fpm

Есть два хоста с пулом PHP-FPM каждый - one.com и two.com. Я хотел бы, чтобы one.com/two прошел и показал two.com с использованием пула two, но, похоже, у меня возникли трудности.

Через alias и try_files, Мне удалось получить статические ресурсы из файлов two.com, обслуживаемых через. one.com/two/path/to/asset.ext, но запросы PHP, например one.com/two/index.php (и запросы к файлам, которых нет в двух файлах), похоже, возвращаются к последнему правилу и вместо этого показывают страницу 404 приложения one.com.

Вот конфигурация местоположения для 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 - что снова показывает страницу 404 на one.com.

Я сбросил отказ во внешнем местоположении, который останавливает запрос, но вместо этого отказ во внутреннем местоположении не блокирует запрос. По какой-то причине он решает использовать последнее местоположение регулярного выражения в исходном коде.

Итак, я нашел проблему и не очень хорошее решение.

Согласно документации nginx, существует известная ошибка, когда с помощью try_files и alias в том же контексте (что не будет исправлено).

В nginx bugtracker обсуждает ошибку включая дела и то, что на самом деле происходит.

Поэтому мне пришлось изменить мою конфигурацию следующим образом:

Во-первых, необходимо удалить косую черту в конце alias линии как try_files добавит косую черту на себя.

Во-вторых, try_files в первом блоке нужно было дважды префикс имени запроса - вместо /two/index.php, это стало /two/two/index.php (потому что псевдоним обрежет первую часть перед определением следующего блока местоположения).

Наконец, для PHP мне нужно было настроить REQUEST_URI так что вместо /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;