DEV Community

Cover image for Nginx: Everything about proxy_pass

Nginx: Everything about proxy_pass

Daniel Albuschat on August 20, 2019

With the advent of Microservices™, ingress routing and routing between services has been an every-increasing demand. I currently default to nginx f...
Collapse
 
iampeters profile image
Peters Chikezie • Edited

hello, Daniel thanks for this post.

However, I am having trouble passing all paths from a request to the server.

example:

servername = 127.0.0.1;

location / {
proxy_pass 192.168.4.22:3000/;
}

I want all requests with dynamic paths coming from e.g 127.0.0.1/ be matched to the above location and passed to the proxy.

I get a 404 from the server when my URL looks like 127.0.0.1/foo/bar but when its just 127.0.0.1, it works fine.

is there something i am not doing right?

Collapse
 
danielkun profile image
Daniel Albuschat • Edited

Hey Peters,

was it just a formatting issue in the comment, or are you missing the // in http://127.0.0.1 in the proxy_pass statement?

Collapse
 
iampeters profile image
Peters Chikezie

Hi Daniel,

It's a formating issue.

Thread Thread
 
danielkun profile image
Daniel Albuschat

Hm... looks correct, though. Maybe the error lies elsewhere?

Thread Thread
 
iampeters profile image
Peters Chikezie

Any idea where to look?

I have two sites enabled. The default nginx site running on port 80 and my API site running on a different port.

Thread Thread
 
danielkun profile image
Daniel Albuschat

Oh, then you forgot to provide the correct port in the URL. What you posted uses the default port 80, so it uses the default nginx site. Use http://127.0.0.1:<you-port>/foo/bar

Thread Thread
 
iampeters profile image
Peters Chikezie

I actually have the correct port in the file. The one I posted here is just an example. The IP is different

Thread Thread
 
iampeters profile image
Peters Chikezie • Edited

Hi Daniel,

Here is how the site looks

upstream backend {
 server 192.168.34.23:3000;
}
server {
        listen 5000 default_server;
        listen [::]:5000 default_server;

        root /var/www/html;
        index index.html index.htm index.nginx-debian.html;

        server_name http://example.com;

         location / {
                proxy_pass http://backend/;
                try_files $uri $uri/ =404;
        }
}
Thread Thread
 
iampeters profile image
Peters Chikezie

i am thinking, could the root there be the problem?

Thread Thread
 
iampeters profile image
Peters Chikezie

I have removed it and it's still the same thing.

Thread Thread
 
iampeters profile image
Peters Chikezie • Edited

Hi again Daniel,

I have been able to solve it.

I had to comment this line in the location

location / {
                proxy_pass http://backend/;
                #try_files $uri $uri/ =404;
        }

Thanks for your time. It's really appreciated

Collapse
 
aditodkar profile image
Aditya Todkar • Edited

In my case I have react + node app + nginx setup and I want to run webflow website only on /blog/* routes. I have added location blog like this:

location /blog {
      proxy_pass https://myblog-blog.webflow.io;
}
Enter fullscreen mode Exit fullscreen mode

But in that case react + node routes and /blog/* routes work fine. Only issue is /blog route gives 404. Any suggestions on what can be done to fix it?

Collapse
 
danielkun profile image
Daniel Albuschat

Heya Aditya!

Could you have a closer look at which server gives you the 404? i.e. does the server logs of myblog-blog.webflow.io show an incoming request that is answered with 404, or is nginx already giving the 404? Maybe you can tell from how the 404 page looks like.

Collapse
 
aditodkar profile image
Aditya Todkar

404 page of webflow is displayed. Do you think this university.webflow.com/lesson/href... can help in my case? I am currently not using paid plan so cannot use href-prefix. So I wanted to know if there is something which I can do in nginx config file.

Collapse
 
pinsard profile image
Gustavo Pinsard

Daniel,
I ended up here by chance. However, I was so impressed by the good work you've done in organizing this article that I decided to join dev.io - so I could post this and hopefully contribute back to the community.
This article is both useful and inspiring. Thanks!

Collapse
 
thecodingalpaca profile image
Carlos Trapet

"with no plausible reason or experience to back this decision, just because it seems to be the most used tool currently" - we all do, mate. Props for being honest though!

Really useful article, I wish I'd had this when I started my first job.
Back then I just assumed nginx was magic.

Collapse
 
sansnom profile image
sansnom

I was completely clueless why the proxy_pass wasn't working with the "set directive". Thanks for sharing. :)

In fact, the "set directive" is also the only way to force nginx to resolve the domain name again (using the parameters defined in the resolver). Otherwise, it will be cached forever...

Collapse
 
sielaq profile image
Wojciech Sielski

"is that nginx is very picky about hostname resolution. For some unexplainable reason, nginx will try to resolve all hosts defined in proxy_pass directives on startup"

In some particular use-cases - especially when using static configuration - this is THE main reason why nginx is not production ready. One temporarily unresolved backend host can cause nginx farm not restartable. This is exact opposite behavior from very disliked nowadays: Apache httpd.

From the other hand for dynamic generated configuration this is a good tool, but has many good successors too: traefik, istio, linkerd, fabio...

There is another piece: missing a global configuration ProxyPreserveHost Off - you cannot do that globally in nginx. You need to specify it per each proxy_paas

using proxy_set_header Host foo.bar. That makes config very unreadable.

Collapse
 
coxse profile image
coxse

Hi Daniel,

With regard to the actual URI that is forwarded, is it not $host that you need?

In the attached picture the yellow highlight is $host and the blue is the upstream $upstream.

Anyway, thanks for the post it really helped setting up our nginx proxy with decent logging.

Adrian

Collapse
 
mikegreen profile image
Mike Green

Hi - found this very useful, and have a question around the $upstream variable in the log format. Using nginx 1.24.0.
I couldn't get $server_name to: "$upstream_addr": to work - it barked with nginx: [emerg] unknown "upstream" variable

Based on the variables here - nginx.org/en/docs/stream/ngx_strea..., I changed it to $upstream_addr and it worked.

Entire log:

log_format upstream_logging '[$time_local] $remote_addr - $remote_user - '
      '$server_name to: "$upstream_addr": "$request" upstream_response_time '
      '$upstream_response_time msec $msec request_time $request_time';
Enter fullscreen mode Exit fullscreen mode

Anyone know if this is a variable change or I misunderstood what $upstream in the log format was?

Collapse
 
grantwparks profile image
Grant Parks

Thank you for this article. I couldn't get a location regex to work with proxy_pass that would work with my upstream's routing; you explained why. (I ended up sticking the file name in an X- header and using via proxy_pass_request_headers.) Now I'm trying to figure out how to get the numeric filename that nginx assigned to my upload in my upstream JS.

Collapse
 
hanxuema profile image
Xavier

Hi Daniel,

First of all, thanks for the post.

I am facing the same issue with nginx does not start when not all upstream hosts are available.
I was trying to reverse proxy the

public.domain.com/mydomain/dev06/api ===>

aws-mydomain-dev06.aws.org/api/

so I changed it to following,

location ~ ^/mydomain/dev06/(.*)$ {
    resolver 10.43.83.2;

    set $upstream https://aws-mydomain-dev06.aws.org/; 

    access_log  /var/log/nginx/access.dev06.log upstream_logging;
    error_log  /var/log/nginx/error.dev06.log debug;

    proxy_pass $upstream/$1$is_args$args;
 }
Enter fullscreen mode Exit fullscreen mode

it returns 404, not found

using string proxy_pass aws-mydomain-dev06.aws.org/; works fine

Is there something I am not doing right? Or where can I have a look to fine out more?

Regards

Collapse
 
posedge profile image
posedge

Thanks for sharing <3 I agree, that unintuitive config can drive someone crazy. Especially the relevance of the slashes.

Collapse
 
mudrii profile image
Ion Mudreac

Thank you, Daniel, for sharing your experience with proxy_pass issues, very useful

Collapse
 
msoup profile image
Dave

This was incredibly detailed and clear. Thank you so much for sharing what you found. You're helping people more than a year down the road :)

Collapse
 
amir_shiri_5a8699c8e12e15 profile image
Amir Shiri

Excellent article! Really explains some nasty gotchas with proxy_pass.

A great follow up will be to get the actual uri that is forwarded to $upstream.

Collapse
 
mralexandrelise profile image
M. Alexandre J-S William ELISÉ

Hi Daniel,
This is a very enlighting article for me. Now I understand better how proxy_pass directive works. Thanks a lot for this article.