Nginx catch and rewrite all requests begining with /api to proxy - nginx

I want to redirect all requests that have /api/ (http://example.com/api/) to my proxy application and drop the /api in the process. I have tried this but I get a 404 when curling it. It doesn't reach the application, I'm thinking it's something to do with the rewrite but I'm not sure if it's correct.
location ~ ^/api {
rewrite ^/api/(.*) /$1 break;
proxy_pass http://127.0.0.1:8070;
}
The following works when hard-coded. It redirects me to my application /error.
location = /api/error {
proxy_pass http://127.0.0.1:8070/error;
}
For example, I want http://example.com/api/login to hit my proxy application like so http://example.com/login.

This works for me. The $1$is_args$args part passes every thing after the /api in the URL. Now when hitting my domain, example.com/api/something passes /something to my proxy application.
location ~/api(.*)$ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8070$1$is_args$args;
}

Related

nginx - how to have proxy pass render a subdomain on the page?

We have a PHP server with Nginx running. On a separate server hosted by Vercel we have a Next.js app running. We've deployed the Vercel app to a subdomain of our main domain: https://vercel.employbl.com/ Our domain is hosted by Cloudflare and we linked it to Vercel by adding a CNAME record like so:
What I'm trying to do is have our main jobs page instead Render the jobs page of the Vercel app. So user enters https://www.employbl.com/jobs but the Next.js app with the matching path https://vercel.employbl.com/jobs renders instead while keeping "employbl.com/jobs" as the URL.
This is the Nginx config we have currently using proxy_pass. Unfortunately I'm getting a 404 error from Vercel when I navigate to "employbl.com/jobs" using this Nginx config:
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location /jobs {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_pass https://vercel.employbl.com/jobs;
}
This renders the page from Vercel: 404 - Code: DEPLOYMENT_NOT_FOUND but the site is working at the URL provided in the nginx config.
How can I configure Nginx so that when the user navigates to "employbl.com/jobs" the https://vercel.employbl.com/jobs page renders?
Try it like this, with trailing slash after the location directive (/jobs/). Then take /jobs off the proxy URL. I think your location path /jobs is being handed to the proxy_pass and ending up doubling the /jobs/ part somehow. Because with no trailing slash it passes that forward. So try:
location /jobs/ {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_pass https://vercel.employbl.com; #removed jobs
}
Edit: On my server I can only get it to work this way. Both location directive and proxy URL end in a slash. From what I've read, this should make it drop the location directive path, instead of passing it on.
location /jobs/ {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_pass https://vercel.employbl.com/jobs/;
}
We ended up getting it working like this. Needed a separate entry to point to files for the _next directory that holds our assets. I think the primary fix was having resolver 8.8.8.8;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location /jobs {
resolver 8.8.8.8;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass https://vercel.employbl.com/jobs;
}
location ~ ^/_next/(.*)$ {
resolver 8.8.8.8;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass https://vercel.employbl.com/_next/$1;
}

Nginx redirects instead of doing reverse proxy with proxy_pass

I have an nginx running on a docker container, which serves a web client.
I want to proxy requests from the client, so that the nginx will pass the POST requests to the server, since the actual destination endpoint is not accessible to the client.
This is the location directive:
location /zipkin {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host:$server_port;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header Host $host;
proxy_pass http://my-ip:9411/;
}
The client makes requests to http://localhost:8080/zipkin/api/v2/span, which I want the nginx to pass (without redirection) to http://my-ip:9411/api/v2/span.
What happens in practice is that I get a 301 response (to http://localhost:8080/api/v2/span), and the POST is never sent to the destination.
Edit: another try that returns 404 -
location /zipkin/ {
rewrite ^/zipkin/(.*) /$1 break;
proxy_pass http://my-ip:9411$uri; # tried 9411;, 9411/, 9411$uri, 9411$uri/
}
Here $uri is /api/v2/span.
The solution in the end was:
location ~ ^/zipkin(/?)(.*) {
proxy_pass http://my-ip:9411/$2;
}
One of my tries was ^/zipkin(.*) but it evidently didn't work.
Probably the / after the /zipkin is problematic, so (/?) removes it,
And that leaves the (.*) the clean part of the url which needs to be attached to the proxy_passed url.

How do I rewrite request_uri variable in a location match

Java backend give me several interfaces like:
/admin/login
/client/query
/agent/update
I am a frontend engineer and I have to use these interfaces with ajax. Because we will deploy our projects on the same server, so I need to use a nginx proxy to direct those ajax request to the java service. But as you can see the interfaces start with different paths, so I prefixed them with "/api" in my code, and also configure nginx as below
axios.post('/api/admin/login'),
axios.post('/api/client/query'),
axios.post('/api/agent/update')
location /api {
proxy_pass http://127.0.0.1:8080$request_uri;
proxy_set_header Host 127.0.0.1;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
here my problem come:
Actually the java service get the request path: /api/admin/login, not /admin/login, so they can not handle that request. Can I rewrite my request_uri in nginx so that java get requests without /api prefix?
You don't need any rewrites for this. Use following location block:
location /api/ {
proxy_pass http://127.0.0.1:8080/;
proxy_set_header Host 127.0.0.1;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
See more info about slashes in proxy_pass directive here.
Copy pasted and adapted from a different question but should do the trick.
location /api {
rewrite ^/api(/.*)$ $1 last;
}

nginx reverse proxying multiple application requesting similar assets

I have several applications located at:
http://www.foo.com:80
http://www.bar.com:42
http://www.baz.com:1337
that I am attempting to reverse proxy with one nginx machine. the issue I have right now is that these applications are requesting files that are identical in name, but not identical in content:
location /bootstrap.css {
proxy_pass http://www.foo.com:80/bootstrap.css;
}
location /bootstrap.css {
proxy_pass http://www.bar.com:42/bootstrap.css;
}
location /baz {
proxy_pass http://www.baz.com:1337;
}
location /foo {
proxy_pass http://www.foo.com:80/;
}
is it possible for me to re-write all responses coming from a particular application server to point to it's application subfolder?
ex: redirect
http://www.foo.com:80/*
to
/foo
You can setup something like:
location /foo {
proxy_pass http://www.foo.com:80;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
However, your application foo might need to know about this. See this post for example.
EDIT:
Nginx might be able to do what you want by using sub_filter from ngx_http_sub_module
Try the example in: answer 1 and answer 2

Nginx - Forward root-level URL (eg, favicon.ico) to Amazon S3?

I'm trying to configure my nginx server to serve root level assets, like www.domain.com/favicon.ico, from S3.
I think, but am not sure, that I'm supposed to proxy_pass to accomplish this. I'm also stuck on the location regex:
server {
listen 80;
server_name *.domain.com
# This is where I'm trying to catch URLs like /favicon.ico
location ~* /*\.(xml|txt|png|ico)$ { # wrong
proxy_pass http://<s3_bucket>?? # wrong
}
# Everything else goes to gunicorn/Django.
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
It's right to do this using proxy_pass. If you have problem you can set error log to debug level to trace the problem. From the trace log, you should focus on two points:
Whether /*\.(xml|txt|png|ico)$ match your requests?
Whether the url being passed is right and access successfully?

Resources