Директивы NGINX try_files + alias
Я пытаюсь подавать запрос в /blog подкаталог сайта с кодом php, находящимся в папке за пределами корневого каталога документа. Здесь моя конфигурация хоста:
server {
server_name local.test.ru;
root /home/alex/www/test2;
location /blog {
alias /home/alex/www/test1;
try_files $uri $uri/ /index.php$is_args$args;
location ~ \.php$ {
fastcgi_split_path_info ^(/blog)(/.*)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
include fastcgi_params;
}
}
}
И я получаю запросы, например
wget -O - http://local.test.ru/blog/nonExisting
просто код файла index.php из папки /home/alex/www/test 2/.
Однако эта конфигурация:
server {
server_name local.test.ru;
root /home/alex/www/test2;
location /blog {
alias /home/alex/www/test1;
try_files $uri $uri/ /blog$is_args$args;
index index.php;
location ~ \.php$ {
fastcgi_split_path_info ^(/blog)(/.*)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
include fastcgi_params;
}
}
}
дает мне файл index.html из /home/alex/www/test 2/.
Пожалуйста, дайте мне ключ - почему? И как я могу заставить NGINX обрабатывать /home/alex/www/test 1/index.php вместо?
Ответы
Ответ 1
Это давняя ошибка в nginx. Но вы можете работать с помощью директивы root
. Вид взлома, но по крайней мере он работает.
server {
index index.php;
root /home/alex/www/test2;
server_name local.test.ru;
location /blog {
root /home/alex/www/test1;
try_files $uri $uri/ /blog$is_args$args;
}
}
Ответ 2
Мы не смогли заставить его работать, указав корень в блоке местоположения. Решение для нас состояло в том, чтобы вместо этого использовать псевдоним. Обратите внимание, что необходимо повторить путь местоположения дважды в директиве try_files, а затем также в блоке конфигурации .php:
server {
server_name localhost;
root /app/frontend/www;
location /backend/ {
alias /app/backend/www/;
# serve static files direct + allow friendly urls
# Note: The seemingly weird syntax is due to a long-standing bug in nginx: https://trac.nginx.org/nginx/ticket/97
try_files $uri $uri/ /backend//backend/index.php?$args;
location ~ /backend/.+\.php$ {
include fastcgi_params;
fastcgi_buffers 256 4k;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_param HTTPS $proxied_https;
fastcgi_pass phpfiles;
}
} # / location
}
Источник: nginx/conf.d/app.conf из debian-php-nginx stack в проект docker-stack
Ответ 3
Существует еще одно обходное решение, которое дает большую гибкость. Он состоит из директивы proxy_pass
, которая указывает на 127.0.0.1 и другой блок server
.
В вашем случае это должно выглядеть так:
upstream blog.fake {
server 127.0.0.1;
}
server {
server_name local.test.ru;
root /home/alex/www/test2;
index index.html;
location /blog {
proxy_pass http://blog.fake/;
}
}
server {
server_name blog.fake;
root /home/alex/www/test1;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php(/|$) {
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTPS off;
}
}