nginx 从与 / 不同的路径配置 /folder 运行

nginx configure /folder run from a different path than the /

我有一个问题 运行 /folder 来自与主网站不同的路径。

我的 nginx.conf 该部分看起来像这样:

        location ~ \.php$ {
            try_files               $uri = 404;
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_param       SCRIPT_FILENAME $request_filename;
            fastcgi_pass            unix:/var/run/php/php7.2-fpm.sock;
            fastcgi_index           index.php;
           include                 fastcgi_params;
            include                 fastcgi.conf;
    }


location ~ /folder {
        alias /srv/http/folder;
    try_files $uri $uri/ @folder;

    location ~ \.php$ {
                fastcgi_param SCRIPT_FILENAME $request_filename;
                fastcgi_pass   unix:/var/run/php/php7.2-fpm.sock;
                include        fastcgi.conf;
        }
}

location @folder {
    rewrite /folder/(.*)$ /folder/index.php?/ last;
}

在 error.log 我可以看到以下内容:

2020/06/03 09:05:26 [error] 25966#25966: *1 FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream, client: 172.21.2.46, server: example.com, request: "GET /folder/xxx_v6.15.11/Resources/images/redcaplogo.gif HTTP/1.1", upstream: "fastcgi://unix:/var/run/php/php7.2-fpm.sock:", host: "example.com"

有什么解决方法的建议吗?

正则表达式位置从头到尾匹配,第一个找到的匹配由 nginx 处理。当您收到 /folder/script.php 的请求时,它由第一个位置块处理。尝试交换这两个位置。此外,您为什么不在第二个位置块中包含 fastcgi_params

更新

我做了一些调试,让我们看看你的代码(假设位置块已经交换):

location ~ /folder {
    alias /srv/http/folder;
    try_files $uri $uri/ @folder;

    location ~ \.php$ {
        fastcgi_param  SCRIPT_FILENAME $request_filename;
        fastcgi_pass   unix:/var/run/php/php7.2-fpm.sock;
        include        fastcgi_params;
        include        fastcgi.conf;
    }
}

location ~ \.php$ {
    try_files               $uri =404;
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_param           SCRIPT_FILENAME $request_filename;
    fastcgi_pass            unix:/var/run/php/php7.2-fpm.sock;
    fastcgi_index           index.php;
    include                 fastcgi_params;
    include                 fastcgi.conf;
}

location @folder {
    rewrite /folder/(.*)$ /folder/index.php?/ last;
}

如果我们收到请求 /folder/some/path(并且 folder 中没有 some/path 文件或目录),在嵌套位置内部 nginx 变量将具有以下值:

  • $request_filename: 空字符串(在 folder 目录中没有真正的文件或文件夹 /some/path);
  • $uri: /folder/check.php;
  • $document_root: /srv/http/folder.

如果我们收到请求 /folder/some/path/script.php(并且有一个真正的 PHP 脚本使用此名称),在嵌套位置内部 nginx 变量将具有以下值:

  • $request_filename: /srv/http/folder/some/path/script.php;
  • $uri: /folder/some/path/check.php;
  • $document_root: /srv/http/folder.

此外,当您收到来自文件夹的静态资源请求时,例如 /folder/some/path/static.csstry_files $uri ... 指令将在 /srv/http/folder 中搜索 folder/some/path/static.css 文件目录,这导致检查 /srv/http/folder/folder/some/path/static.css 文件是否存在。

folder 目录中获取文件子路径的可能解决方案之一:

location ~ ^/folder(?<subpath>.*) {
    alias /srv/http/folder;
    try_files $subpath $subpath/ @folder;

    location ~ \.php$ {
        fastcgi_param  SCRIPT_FILENAME $document_root$subpath;
        fastcgi_pass   unix:/var/run/php/php7.2-fpm.sock;
        include        fastcgi_params;
        include        fastcgi.conf;
    }
}

location ~ \.php$ {
    try_files               $uri =404;
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_param           SCRIPT_FILENAME $request_filename;
    fastcgi_pass            unix:/var/run/php/php7.2-fpm.sock;
    fastcgi_index           index.php;
    include                 fastcgi_params;
    include                 fastcgi.conf;
}

location @folder {
    rewrite ^/folder/(.*)$ /folder/index.php?/ last;
}

如果您的真实 folder 目录名称与您的 /folder URI 前缀相同,这可以简化:

location ~ ^/folder {
    root /srv/http;
    try_files $uri $uri/ @folder;

    location ~ \.php$ {
        fastcgi_param  SCRIPT_FILENAME $document_root$uri;
        fastcgi_pass   unix:/var/run/php/php7.2-fpm.sock;
        include        fastcgi_params;
        include        fastcgi.conf;
    }
}

...

作为 nginx 文档 states:

When location matches the last part of the directive’s value:

location /images/ {
  alias /data/w3/images/;
}

it is better to use the root directive instead:

location /images/ {
  root /data/w3;
}