1

I'd like to call a named location which handles a reverse proxy directive. So I've tried the following lines in my virtual host section:

upstream node_upstream {
    server 127.0.0.1:8000;
    keepalive 64;
}

server {
  server_name my.host-name.com;
  listen 80;  
  access_log  /home/webhost/logs/my-host-name.access.log;
  error_log  /home/webhost/logs/my-host-name.error.log;

  root /home/webhost/www/my.host-name.com/node-canary/public;
  
  location / {
    index index.html; 
    try_files $uri $uri.html $uri/index.html $uri/ @node;
  }

  location @node {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $http_host;
       
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
        
    proxy_pass http://node_upstream/;
    proxy_redirect off;
    proxy_read_timeout 240s;
  }
}

This is pretty straight forward, but on running it, I get

nginx: [emerg] "proxy_pass" cannot have URI part in location
given by regular expression, or inside named location, or inside
"if" statement, or inside "limit_except" block in 
/home/webhost/sites-enabled/my.host-name.com:29
nginx: configuration file /usr/local/etc/nginx/nginx.conf test failed

For me this means I can't use proxy pass in the @node named location.

So, I tought I could outsmart nginx by simply moving the directives located in the @node location into the root (i.e. /) location. Anything outside remains the same. Like this:

server {
  server_name my.host-name.com;
  listen 80;  
  access_log  /home/webhost/logs/my-host-name.access.log;
  error_log  /home/webhost/logs/my-host-name.error.log;

  root /home/webhost/www/my.host-name.com/node-canary/public;
  
  location / {
    index index.html; 
    try_files $uri $uri.html $uri/index.html $uri/ $uri;

    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $http_host;
       
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
        
    proxy_pass http://node_upstream/;
    proxy_redirect off;
    proxy_read_timeout 240s;
  }
}

But with this setup, something weird happens. When an existing static file is being hit, the request is being answered by the proxy connection (a node app) – not by responding with the static file itself.

That's the only case a request returns a valid response. Any route not matching a static file returns a an nginx 500 server error.

This sort of baffles me up to the point of being flabbergasted.

LongHike
  • 147
  • 5
  • Use `proxy_pass http://node_upstream;` instead of `proxy_pass http://node_upstream/;` - Nginx is complaining about the trailing `/` which you probably don't need anyway. – Richard Smith Jul 30 '22 at 14:51
  • Yes, it was the trailing slash. Thank you so much!!! I've been doing this for so long now and still step into the same traps. I you turn you comment into an answer, I'll mark it of as valid answer for your credits. – LongHike Jul 30 '22 at 14:56

1 Answers1

1

The error message "proxy_pass" cannot have URI part in ... is simply referring to the trailing / in your proxy_pass statement.

Use:

proxy_pass http://node_upstream;

instead of:

proxy_pass http://node_upstream/;

See this document for details.

Richard Smith
  • 11,859
  • 2
  • 18
  • 26