Search code examples
nginxnginx-locationnginx-reverse-proxyminio

Nginx Fails with my variables in location


So I am trying to set up an nginx default.conf and I'm having trouble using variables. I want to capture the subdomain as the $subdomain variable and use it a few times in the default.conf.

Here is my config:

server {
     listen 80;
     server_name  ~^(?<subdomain>.+)\.example\.com$;
     # To allow special characters in headers
     ignore_invalid_headers off;
     # Allow any size file to be uploaded.  
     # Set to a value such as 1000m; to restrict file size to a specific value
     client_max_body_size 0;
     # To disable buffering
     proxy_buffering off;
     location / {
       rewrite ^/$ /$subdomain/index.html break;
       proxy_set_header Host $http_host;
       proxy_pass http://minio-server:9000/$subdomain/;
       #health_check uri=/minio/health/ready;
     }
}

Unfortunately the presence of the $subdomain variable in the location block fails nginx entirely every time. If I were to replace $subdomain in the location block with tester as a static value then everything works.

How to correctly use the $subdomain variable here???

This question is a somewhat of a followup on this issue: k8s-ingress-minio-and-a-static-site. In that issue I was trying to use Ingress to reverse proxy to a minio bucket, but to no avail. Now I'm just trying to go through Nginx directly but my vars ain't workin.

Updates

So it seems the proxy_pass will not resolve the host correctly if there is a variable in the URL.

Tried two things:

  1. set the resolver like so: resolver default.cluster.local. I tried a bunch of combos for the fqdn of the kube-dns but to no avail and kept getting minio-server can't be found.

  2. Simply don't use variables like Richard Smith mentions below. Instead rewrite everything then proxy pass. However I don't understand how this would work and I get very useless errors like so: 10.244.1.1 - - [07/Feb/2019:18:13:53 +0000] "GET / HTTP/1.1" 405 291 "-" "kube-probe/1.10" "-"


Solution

  • According to the manual page:

    When variables are used in proxy_pass: ... In this case, if URI is specified in the directive, it is passed to the server as is, replacing the original request URI.

    So you need to construct the complete URI for the upstream server.

    For example:

    location = / {
        rewrite ^ /index.html last;
    }
    location / {
        proxy_set_header Host $http_host;
        proxy_pass http://minio-server:9000/$subdomain$request_uri;
    }
    

    It may be better to use rewrite...break and use proxy_pass without a URI.

    For example:

    location / {
        rewrite ^/$ /$subdomain/index.html break;
        rewrite ^ /$subdomain$uri break;
        proxy_set_header Host $http_host;
        proxy_pass http://minio-server:9000;
    }