0

I have a nginx webserver configured as follows:

server {
    listen       3000;
    listen  [::]:3000;
    server_name .+;

    add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;

    access_log  /var/log/nginx/access.log main;
    error_log   /var/log/nginx/error.log debug;

    gzip on;
    gzip_static on;
    gzip_comp_level 9;
    gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript image/jpg image/png image/jpeg image/svg;
    gzip_min_length 256;
    gzip_vary on;

    index index.html;
    root /usr/share/nginx/html;

    set $api https://some_ip:some_port;

    location ~ ^/api(/.*)$ {
        rewrite ^/api(/.*)?$ $1 break;
        proxy_pass $api$request_uri;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Host $server_name;
    }

    location / {
        try_files $uri $uri/ /index.html;
    }

    client_max_body_size 1M;
    keepalive_timeout 10;
}

From my application, I make a request to the api as follows:

const res = await fetch(`api/sub`, {
    method: 'POST',
    headers: {
          ...headers
    },
    body: ...body,
});

If I make the request on my dev server with a proxy, it gets resolved to

https://some_ip:some_port/sub

and everything is fine.

If I make the request on my production nginx server, I get a Error 502: Bad Gateway.

In the error logs, it says: no resolver defined to resolve some_ip.

My suspicion is, that the proxy does not resolve my request as I intend. Is there any way to see the address, my request is resolved to?

I already tried to add $upstream_addr to the logging in the config, but it tells me invalid parameter.

wittn
  • 298
  • 5
  • 16
  • Your `proxy_pass` statement contains a variable, so Nginx [requires a resolver](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass). If you do not wish to use a resolver, use `proxy_pass https://some_ip:some_port;` instead. – Richard Smith Jan 16 '23 at 15:17
  • @RichardSmith Depending on the request, I need to access different subpages of the api, so I need to add $request_uri, right? So I definitly need a resolver, or is that treated differently? I have tried adding a resolver via "resolver 127.0.0.11 valid=10s;" before, but then I get a "send() failed (Connection refused) while resolving". – wittn Jan 16 '23 at 15:19
  • I put the resolver no to the dns configuration of my container and this made the bad gateway error disappear. Now I get an error 403: Forbidden. Could it still have something to do with some incorrect configuration or is it a problem on the apis side? – wittn Jan 16 '23 at 15:52
  • `proxy_pass` passes the requested URI to the upstream server. There is no need to add `$request_uri`. Also, `$request_uri` is probably the wrong value. You have a `rewrite` statement that is currently ignored. Are you trying to remove the `/api` part from the URI before passing it upstream? – Richard Smith Jan 17 '23 at 08:03
  • @RichardSmith Yes, precisely, I am trying to remove it (not removing it was an error I observed before). If it is ignored currently, how can I fix this? I see, so it is enough to provide the ip and port of the api to proxy pass? – wittn Jan 17 '23 at 14:44
  • If you use `proxy_pass https://some_ip:some_port;` with nothing after the port number, the `rewrite...break` will work as expected. Alternatively, I have posted an answer that avoids the `rewrite...break` statement. – Richard Smith Jan 17 '23 at 14:58

1 Answers1

0

The simplest solution is to use a built-in feature of proxy_pass when used with a prefix location.

location /api/ {
    proxy_pass https://some_ip:some_port/;
    ...
}

This form removes the need for a rewrite...break statement. Notice the trailing / in both the location and proxy_pass values. See the proxy_pass documentation.

This solution removes /api from the URL, and also avoids the need for a resolver.

Richard Smith
  • 45,711
  • 6
  • 82
  • 81
  • Using this, I get a "403: forbidden" in my application when accessing the api. The nginx error logs tell me: "client timed out (110: Operation timed out) while waiting for request". Could this still be connected to my problem before or is it some other problem? It works fine using the vue proxy on my development server. – wittn Jan 23 '23 at 10:01