Nginx多个位置,每个位置都有自己的根

时间:2017-01-19 14:40:01

标签: nginx nginx-location

server {
  listen 80;
  server_name ~^(?<cc>.+?).local.solar.bc.digital$;
  client_max_body_size 1m;

  root /home/vagrant/sites/$cc/_www/;
  index  index.html index.htm index.php;
  error_page 404 /index.php;
  access_log /var/log/nginx/$cc-access.log;
  error_log /var/log/nginx/$cc-error.log;
  charset utf-8;
  sendfile off;

  location / {
    root /home/vagrant/sites/$cc/_www/php/;
    try_files $uri $uri/ /index.php?$query_string;
  }

  location /shop/ {
    # root /home/vagrant/sites/$cc/_www/bcshop/;
    try_files $uri $uri/ /index.php?$query_string;
  }

  location ~ \.php$ {
    fastcgi_index index.php;
    fastcgi_split_path_info ^(.+\.php)(/.*)$;
    include /etc/nginx/fastcgi_params;
    fastcgi_pass 127.0.0.1:9000;
    fastcgi_param SCRIPT_FILENAME $request_filename;
    fastcgi_param APP_ENV dev;
    fastcgi_param PLATFORM_ENVIRONMENT local;
    fastcgi_read_timeout 300;
    fastcgi_buffers 16 16k;
    fastcgi_buffer_size 32k;
  }

  location ~ /\.ht {
    deny all;
  }
}

对,给定上面的配置。如果你看到我想要做什么,知道它不起作用!

一些细节:

  1. 我有一般的'root',因为没有我得到错误。
  2. 这是在用于开发的本地VM上。我们在本地有一个部署工具,对于每个项目(参见上面配置中的$ cc变量),它最多可以部署两个应用程序。不一定都为每个项目部署两者。第一个应用程序部署在/home/vagrant/sites/$cc/_www/php中,第二个应用程序部署在/home/vagrant/sites/$cc/_www/bcshop中(但我可以将其设为shop - 您将从配置中看到原因)
  3. 两个应用程序都在Drupal上运行,因此负载的方式是相同的。我根本无法使它们发挥作用。对于我尝试过的大多数小变种,我都找不到文件。
  4. 当我将第二个应用放入/home/vagrant/sites/$cc/_www/shop(而不是/home/vagrant/sites/$cc/_www/bcshop)时,我可以加载其主页,但没有别的。
  5. 当我忽略第二个应用程序并专注于第一个应用程序时,我可以简单地将一般根设置为/home/vagrant/sites/$cc/_www/php并从位置/中删除本地根。这样可行。但是当它被指定为本地根时它不会。在这种情况下,实际上,我在日志中收到此错误:“在stderr中发送的FastCGI:”主要脚本未知“从上游读取响应头”。这仅适用于第一个应用程序。
  6. 如果你想知道为什么将一般根设置为该值,那是因为如果一般根对于匹配的位置是不可验证的,我会在日志中收到错误。有意义吗?
  7. 我想我已经完全涵盖了我所做的所有内容。

    思考?

    我不是nginx的专家,所以我将通过试用和错误,在文档的帮助下以及此处回答的其他问题。但到目前为止,没有快乐。

    谢谢大家。

2 个答案:

答案 0 :(得分:0)

您在_www/bcshop/路径和_www/php/路径中都有PHP文件。如果您希望为两个应用程序使用一个公共location ~ \.php$,则每个应用程序的URI将分别以/bcshop/php为前缀。也就是说,两个应用程序都出现以在子目录中运行。

我怀疑你想为一个应用程序使用/shop前缀,为另一个应用程序使用/前缀。在这种情况下,将需要两个location ~ \.php$块。

一个应用程序从服务器根目录运行:

root /home/vagrant/sites/$cc/_www/php;
location / {
    try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
    try_files $uri /index.php;

    include /etc/nginx/fastcgi_params;
    fastcgi_pass 127.0.0.1:9000;
    fastcgi_param SCRIPT_FILENAME $request_filename;
    ...
}

一个应用程序使用/shop的URI前缀运行,但位于子目录_www/bcshop中:

location ^~ /shop {
    rewrite ^/shop(?:/(.*))?$ /bcshop/$1 last;
}

location ^~ /bcshop/ {
    internal;
    root /home/vagrant/sites/$cc/_www;

    try_files $uri /shop/index.php?$query_string;

    location ~ \.php$ {
        try_files $uri /shop/index.php;

        include /etc/nginx/fastcgi_params;
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_param SCRIPT_FILENAME $request_filename;
        ...
    }
}

^~修饰符可确保location块优先于上面的正则表达式位置块。有关详细信息,请参阅this document

虽然外部URI前缀为/shop,但它会被静默重写为/bcshop,以便我们可以继续使用root指令。有一个alias指令,但它有issues with try_files,并且很难与PHP一起使用。

答案 1 :(得分:0)

根据@RichardSmith的回答,我提出了自己的变体(工作正常)。只是因为重复location ~ \.php$的阻止了我的目标。

...
...
root /home/vagrant/sites/$cc/_www/;
...
...
location / {
  set $actual_root /home/vagrant/sites/$cc/_www/php/;
  set $fastcgi_index /index.php;
  root $actual_root;
  try_files $uri $uri/ $fastcgi_index?$query_string;
}

location /shop/ {
  set $actual_root /home/vagrant/sites/$cc/_www/;
  set $fastcgi_index /shop/index.php;
  root $actual_root;
  try_files $uri $uri/ $fastcgi_index?$query_string;
 }

location ~ \.php$ {
  root $actual_root;
  fastcgi_index $fastcgi_index;
  fastcgi_split_path_info ^(.+\.php)(/.*)$;
  include /etc/nginx/fastcgi_params;
  fastcgi_pass 127.0.0.1:9000;
  fastcgi_param SCRIPT_FILENAME $actual_root/$fastcgi_script_name;
  fastcgi_param PATH_INFO $fastcgi_path_info;
  fastcgi_param APP_ENV dev;
  fastcgi_param PLATFORM_ENVIRONMENT local;
  fastcgi_read_timeout 300;
  fastcgi_buffers 16 16k;
  fastcgi_buffer_size 32k;      
}

...
...