Reputation: 116
I am successfully able to reverse proxy multiple node.js projects to different ports as in the Nginx set up below. What I am trying to accomplish however, is viewing the url as the root when it gets to the Node.js server.
For example, When someone goes to mydomain.com/projects/music_player, is it possible to have the Express application view the request url as just '/' instead of '/projects/music_player'.
My current Nginx setup, and Express configuration example are as follows.
Nginx:
server {
listen 80;
server_name mydomain_name.com;
location / {
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
location /projects/music_player/ {
proxy_pass http://localhost:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
I want to do this:
app.get("/", function (req, res) {
res.sendFile("index.html");
});
app.listen(8000);
Instead of this:
app.get("/projects/music_player", function (req, res) {
res.sendFile("index.html");
});
app.listen(8000);
I am not sure if that is even possible. The reason is that I would like each of my node node.js/express applications to be deployable as standalone applications, without restructuring the code. I am trying to avoid having a bunch of domain names for each project, plus I think it would be pretty cool.
Upvotes: 2
Views: 1931
Reputation: 5742
Yes! Of course you can.
I think the best way to do this is to rewrite your entire program into one express app, but you say you want to avoid this.
Then I think the short way with your current setup is to make each program listen to a different port and then map routes to them in your nginx.
For example:
dog.js
app.get("/", function (req, res) {
res.sendFile("dog.html");
});
app.listen(8001);
cat.js
app.get("/", function (req, res) {
res.sendFile("cat.html");
});
app.listen(8002);
And finally in your nginx config file:
server {
listen 80;
server_name mydomain_name.com;
location / {
proxy_pass http://localhost:8001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
location /cat/ {
rewrite /cat/ / break;
proxy_pass http://localhost:8002;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
Notice the rewrite directive, this prevents for the /cat/
location from being sent to your cat.js
app that only expects the /
route.
Upvotes: 2
Reputation: 122
I ran into this same problem, where I didn't want to fully restructure my backend services while wanting to change the endpoint to match others.
I ended up using node-http-proxy with http-proxy-rules. Grabbing an example from the http-proxy-rules github README, you're solution would resemble the following.
var http = require('http'),
httpProxy = require('http-proxy'),
HttpProxyRules = require('http-proxy-rules');
// Set up proxy rules instance
var proxyRules = new HttpProxyRules({
rules: {
'.*/test': 'http://localhost:8080/cool', // Rule (1)
'.*/test2/': 'http://localhost:8080/cool2/' // Rule (2)
},
default: 'http://localhost:8080' // default target
});
// Create reverse proxy instance
var proxy = httpProxy.createProxy();
// Create http server that leverages reverse proxy instance
// and proxy rules to proxy requests to different targets
http.createServer(function(req, res) {
// a match method is exposed on the proxy rules instance
// to test a request to see if it matches against one of the specified rules
var target = proxyRules.match(req);
if (target) {
return proxy.web(req, res, {
target: target
});
}
res.writeHead(500, { 'Content-Type': 'text/plain' });
res.end('The request url and path did not match any of the listed rules!');
}).listen(6010, cb);
Happy hacking!
Upvotes: 0