基于 uri 路径的 nginx 位置

基于 uri 路径的 nginx 位置

我有一个域名,称为 example.com,其路径为 /test1 和 /test2。

对 http example.com/test1 的请求被发送到 test1.example.com/test1。

对 http example.com/test2 的请求被发送到 test2.example.com/test2。

到目前为止,这个 nginx 配置已经很好地满足了我的要求。

server {

  listen 80 default_server;
  root /usr/share/nginx/html;
  server_name localhost;
  index index.html;
  autoindex on;

  location /test1 {
    resolver ns1.example.com;
    resolver_timeout 5s;
    proxy_pass http://test1.example.com/test1;
    proxy_redirect default;
  }

  location /test2 {
    resolver ns1.example.com;
    resolver_timeout 5s;
    proxy_pass http://test2.example.com/test2;
    proxy_redirect default;
  }

}

如果可能的话,我现在需要改变配置,以便请求能够到达适当的后端,而无需单独添加到 nginx 配置中。

使用子域名代替路径是一个长期选择,但由于其他限制,目前不可行。

如果可能的话,我宁愿将解决方案包含在 nginx 配置中,而不依赖于维护当前 example.com 主机名的数据库。

我需要输入的是第一个斜杠之后和第二个斜杠之前(如果存在)的 uri 路径中的数据。

例如:example.com/debug/index.html。debug 将被解析。debug 可能是也可能不是 example.com 域中的有效主机名。如果它无效(404、500 或 502 错误……可能还有其他错误),则转到一个 catch-all 页面。如果它有效,则将请求定向到 debug.example.com/debug/index.html。

这是我的第一次尝试,但没有成功(虽然找到/加载了基本的index.html,但有太多的重定向错误和在本地文件系统而不是远程文件系统中查找的图像/包含内容)。

是否有人知道我可能缺少什么或知道可以帮助我实现目标的替代方案?

server {

  listen 80 default_server;
  root /usr/share/nginx/html;
  server_name localhost;
  index index.html;
  autoindex on;

  set $frontend_fqdn "nil";
  set $namespace "nil";

  if ($request_uri ~ "^/([A-Za-z0-9-_]+).*$") {
    set $namespace "$1";
    set $frontend_fqdn "$namespace.example.com";
  }

  location / {
    resolver ns1.example.com;
    resolver_timeout 5s;
    error_page 404 500 502 = @fallback;

    if ($frontend_fqdn !~ "nil") {
      proxy_pass http://$frontend_fqdn$request_uri;
    }
    try_files $uri $uri/ =404;
  }

  location @fallback {
    rewrite ^(.*)$ $scheme://$host permanent;
  }

}

预先感谢您的任何帮助。

答案1

类似这样的事情应该可以工作:

server {

  listen 80 default_server;
  root /usr/share/nginx/html;
  server_name localhost;
  index index.html;
  autoindex on;

  location ~ ^/([^/]+) {
    try_files $uri $uri/ @proxy;
  }

  location @proxy {
    resolver ns1.example.com;
    resolver_timeout 5s;
    error_page 404 500 502 = @fallback;
    proxy_pass $scheme://$1.$host;
  }

  location @fallback {
    return 301 $scheme://$host;
  }

}

第一个位置块将匹配所有 URI,并将路径的第一部分保存到 $1。然后,它会尝试提供匹配的本地文件/文件夹(如果存在),否则,它会尝试通过将路径部分作为子域注入来代理到您在问题中提到的服务器。如果失败,它会重定向到预定位置。

相关内容