How to set proxy pass for react app on nginx? - node.js

My react app has got different routes to consume different functionalities
e.x.
localhost:3000,
localhost:3000/Dashboard,
localhost:3000/Hub,
localhost:3000/Person
etc....
I wanted to configure the react app routes in the nginx in the production environment. What I have actually done so far in the nginx configuration at production env is,
server_name api.vesta-project.net;
location /vqcc {
proxy_pass http://localhost:3000/;
}
My problem here is with the current settings, the homepage works well when I say "api.vesta-project.net/vqcc". Whereas, when I click a button that navigates to /Dashboard. I get 404 error as it does not append "vqcc" to the path in the react app internally thus it becomes like api.vesta-project.net/Dashboard" when inspecting the request which is wrong per nginx conf. So I need a solution whenever the client make a request, it should append "vqcc" to the path so that it will become a valid url as per nginx routes.
e.x when client request for api.vesta-project.net/Dashboard, it should become
api.vesta-project.net/vqcc/Dashboard
Pls help me if I can handle this at nginx or package.json without being changing any routes in the react app internally

You can try rewriting the uri in catch-all location.
location / {
rewrite /(.*) /vqcc/$1;
}
location /vqcc{
proxy_pass http://localhost:3000/;
}

Related

Change root folder of expressjs app

I'm trying to set the twilio client quickstart app up in nodejs. I'm using nginx as a reverse proxy so that requests made to http://example.com/calls, nginx routes that to localhost:3000, where I have the twilio nodejs quickstart running. The problem is that expressjs is expecting to serve files as if I were calling http://example.com with no subdirectory.
I understand that I would be able to use app.get, but I'm not sure how in the way this particular app is configured. Right now it has:
const http = require('http');
const path = require('path');
const express = require('express');
const bodyParser = require('body-parser');
const router = require('./src/router');
// Create Express webapp
const app = express();
app.use(express.static(path.join(__dirname, 'public')));// <-Pretty sure I'm supposed to change something here
app.use(bodyParser.urlencoded({extended: false}));
In the index.js that node is running on is at
/var/www/example.com/calls/index.js
The static content that I thought ought to be served is at
/var/www/example.com/calls/public/index.html
How to I change this to make express find the content?
Nodejs is definitely recieving the request. The error is Cannot GET /calls/ and the header X-Powered-By is present and set to Express
EDIT:
I would have liked to follow the instructions here but my at&t firewall isn't letting me make changes. Since I have ports 80 and 443 open already I decided my next best bet was to proxy the application to a subfolder of a domain I already have running on my system. Both of the solutions offered so far allow the index.html file inside of the /public folder to be served, but nginx is failing to serve the js file or the the css files located in the same folder.
app.use('/calls',express.static(path.join(__dirname, '/public')));
is currently serving the index.html file at https://example.com/calls, which is great. What stinks is the nginx somehow isn't passing the requests for https://example.com/calls/site.css along to nodejs.
If I add the line
rewrite ^/cawls(.*)$ $1 break;
then nothing gets found.
Here's the nginx call.
location ~/calls(.*)$ {
# rewrite ^/calls(.*)$ $1 break;
proxy_pass http://127.0.0.1:3000;
}
Here and here are previous questions related to this problem that no one seems to have an answer for.
Twilio developer evangelist here.
The problem here is that express knows nothing of your /calls route. It expects to be serving content at its application root. You could fix this in the app by appending the /calls route to your static middleware, like so:
app.use('/calls', express.static(path.join(__dirname, 'public')));
But that would mean that your express app knows about the rest of the applications that you are reverse proxying with nginx. Instead, I would suggest you update your nginx config to proxy pass but strip the /calls route for your express app.
I'm guessing you have some nginx config that looks a bit like this:
location /calls {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header HOST $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://localhost:3000;
proxy_redirect off;
}
If you add one line to this block it should strip the /calls route for the benefits of your express app.
rewrite ^/calls(/.*)$ $1 break;
Let me know if either of these things helps!
I haven't seen express.static used for HTML. What about serving it from a route?
app.get('/', function(req, res) {
res.sendFile(path.join(__dirname, 'public/index.html'));
})

Static files are served locally but not through nginx

I'm running a node.js API on a VPS, which is served by nginx on Ubuntu 13.04.
I'm using restify and serving static files like this:
server.get(
/\/static\/?.*/,
restify.serveStatic({
directory: __dirname // => /home/misha/rxviz-api
})
);
Here is the relevant bits from nginx config:
server {
listen 80;
server_name api.rxviz.com;
location / {
proxy_pass http://localhost:4010/;
}
}
(full config is here)
When running:
curl http://localhost:4010/static/.well-known/acme-challenge/test.json
on the VPS, I get the contents of test.json.
However, when navigating to:
http://api.rxviz.com/static/.well-known/acme-challenge/test.json
in a browser, I get 404.
nginx error logs show that /opt/nginx/html/static/.well-known/acme-challenge/test.json not found.
Why does nginx trying to access test.json in /opt/nginx/html rather than /home/misha/rxviz-api?
Few more points:
static directory permissions are drwxrwxr-x
I can access http://api.rxviz.com/ in the browser successfully
It's hard for me to be sure, as I can't test it, BUT..
I think you have a problem with the nginx settings:
location /static/ {
alias /home/misha/rxviz-api/static/;
}
the /static is appended to the alias including the location part, so it's searches for /home/misha/rxviz-api/static/static
This is going to return 404 since there is no static/ within static/
try to fix to:
location /static/ {
alias /home/misha/rxviz-api/;
}
....
...
and also I wanted just to mention.
It's seems like your node server (using restify) is serving the content as you wanted (127.0.0.1:4010/static/... works as you say),
BUT note that nginx is anyway not redirecting any of the /static calls into your node, so your node restify is unused.
why?
This section:
location /static/ {
alias /home/misha/rxviz-api/static/;
}
tells nginx to NOT redirect those /static calls into your node service, and instead try to find and serve the file from the local path.
so if you want to use the restify... just remove this entire location /static part, and your node will serve those files too.

Nginx fails to receive custom header when Redirected by Proxy server Node

I am running an NGINX server pointing to my proxy server which is running on Node. I am redirecting to app/ from node using express redirect. I am also passing a custom header using res.set("X-Custom-Header","XXX"); before the redirect. But the same header is not retrieved on app/ route on NGINX. Is there anything I am missing?
By default, nginx does not pass headers containing underscores.
Try:
underscores_in_headers on;
See this document for details.

nginx proxy to remote node.js express app in subdirectory

I am completely stuck with a situation where I want to have several node applications on one server. I get this working fine by having the applications running on different ports. I can access the applications by putting in the ip address with port.
I would like to proxy the applications from my nginx server by using different sub-directories like so:
my.domain
location /app1 {
proxy_pass http://10.131.6.181:3001;
}
location /app2 {
proxy_pass http://10.131.6.181:3002;
}
Doing this I had to move the all the express routes to /app1 for application1. This works but now I am stuck with the static files.
I can now access the application with http://10.131.6.181:3001/app1 which is great, but via http://my.domain/app1 the static files are not loaded.
The static files can be accessed directly http://10.131.6.181:3001/css but not via the proxy http://my.domain/css
Ideally I would like to have the applications on different ports without the sub-directory in the express routes but only sub-directories in the proxy. I tried to put my head through the wall for the last 5 hours but didn't achieve anything.
Now I would happy if can at least get the static files via the nginx proxy.
An updated answer for anyone who needs:
instead of
location /app1 {
proxy_pass http://10.131.6.181:3001/app1;
}
use
location /app1/ {
proxy_pass http://10.131.6.181:3001/;
}
or if on local
location /app1/ {
proxy_pass http://localhost:3000/;
}
This is the correct way and this way you will not need to modify express. Express will receive only the part after /app1/
I finally worked it out after a google surge.
I added the directories to the nginx proxy_pass
my.domain
location /app1 {
proxy_pass http://10.131.6.181:3001/app1;
}
location /app2 {
proxy_pass http://10.131.6.181:3002/app2;
}
And I had to change the express applications to use the subdirectory
app.use('/app1', express.static(path.join(__dirname, 'public')));
app.use('/app1'', require('./routes'));
In the router I had to prefix all the redirects.
router.get('/logout', function (req, res) {
req.logout();
res.redirect('/app1/login');
});
The static files are called like so from html
<link rel="stylesheet" href="/app1/css/style.css"/>
A bit of a pain to change all the redirects and static url. I am sure there is a smarter way by setting a global variable in my node-express app. If anybody knows an easier way please post...

Nginx rewrite rule for Node.js

I'm setting up Nginx as a reverse proxy for a Node.JS application.
Node app listens on localhost:3003 and proxy is set up like this:
location /otfb {
proxy_pass http://127.0.0.1:3003;
#...
}
Now the problem is that if I access server like this:
http://server.xyz/otfb/someresource
then it is passed to Node.JS as
http://localhost:3003/otfb/someresource
But correct will be
http://localhost:3003/someresource
Show how to set up rewrite rule so that otfb will be removed by Nginx before request is passed to Node.JS
It turned out that rewrite isn't needed at all
Working configuration:
location /otfb/ {
proxy_pass http://127.0.0.1:3003/;
#...
}
Just slashes was missing at the end of URIs

Resources