Laravel — Nginx, корневой каталог на основе пути

У меня возникла ситуация, когда мне нужно обслужить все запросы от https://example.com/api/v1 из другой папки скажем /var/www/firstversion/public и https://example.com/api/v2 из другой папки /var/www/secondversion/public

Ниже показано, как выглядит моя текущая конфигурация

server {
        root /var/www/firstversion/public/;
        index index.html index.php index.htm index.nginx-debian.html;
        server_name example.com;

        location / {
              try_files $uri $uri/ /index.php$is_args$args;
        }
        location /api/v2/ {
                alias /var/www/secondversion/public/;
                try_files $uri $uri/ /index.php$is_args$args;
        }
        location ~ \.php$ {
                include snippets/fastcgi-php.conf;
                fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
              
        }
        location ~ /\.ht {
                deny all;
        }

}

Проблема здесь в том, что я всегда получаю ответ от /var/www/firstversion/public/. Однако, чтобы проверить, выбран ли блок местоположения, я попытался добавить return 302 https://google.com, и это сработало. Таким образом, шаблон местоположения совпадает, но почему-то не работает alias/root. Может ли кто-нибудь указать в правильном направлении или что мне не хватает?

🤔 А знаете ли вы, что...
Laravel позволяет создавать красочные и интерактивные интерфейсы с использованием Blade и Vue.js.


30
1

Ответ:

Решено

Самое первое, что вам не хватает, это то, что последний параметр директивы try_files обрабатывается как новый URI для переоценки с самого начала. То есть после того, как запрос типа /api/v2/some/route обрабатывается вашим location /api/v2/ { ... } и в вашей локальной файловой системе нет такого физического файла или каталога /var/www/secondversion/public/some/route, происходит внутренняя перезапись в /index.php$is_args$args. После этого переписанный URI обрабатывается вашим обработчиком location ~ \.php$ { ... } PHP-FPM, который наследует свой корень как /var/www/firstversion/public/ из верхнего уровня конфигурации.

Директива try_files при использовании с alias имеет давно существующую побочные эффекты, которую я не думаю, что она будет исправлена, по крайней мере, до тех пор, пока не будет изменена основная версия nginx, поскольку существует слишком много конфигураций, которые каким-то образом адаптированы для этих эффектов. Когда вам нужно разместить какую-то сложную систему на основе PHP (например, WordPress) с некоторым префиксом URI, можно использовать обходной путь, подобный показанному здесь, с объявлением вложенного обработчика PHP. Однако ваш случай совершенно другой, и на самом деле, чтобы просто обслуживать какой-то API, вам не нужен такой сложный подход.

Вы должны понимать, что вам вообще не нужно зацикливаться на этом location ~ \.php$ { ... } для обработки файла PHP через демон PHP-FPM, а также вам не нужно зацикливаться на каком-то предопределенном обработчике PHP snippets/fastcgi-php.conf (который я полагаю что-то вроде показанного здесь). Вместо этого, если все запросы должны обрабатываться исключительно с помощью index.php из первого или второго серверного приложения, вы можете определить свой собственный обработчик PHP следующим образом:

map $uri $api_root {
    ~^/api/v2    /var/www/secondversion/public;
    default      /var/www/firstversion/public;
}
server {
    ...
    location ^~ /api/ {
        include fastcgi_params;
        # redefine some FastCGI parameters
        fastcgi_param DOCUMENT_ROOT $api_root;
        fastcgi_param SCRIPT_NAME /index.php;
        fastcgi_param SCRIPT_FILENAME $api_root/index.php;
        fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
    }
}