Multiple node apps with NGINX in sub-directories - node.js

I currently have a digital ocean droplet connected to a domain. On the server, I'm running NGINX and trying to reverse proxy multiple node apps to it. Currently, my root directory has one node express app, at location / .
I'm trying to connect another node express application, to another sub directory. Here's the nginx config file:
server {
listen 80;
server_name servername.com;
# my root app
location / {
proxy_pass http://127.0.0.1:6001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
# new app
location ~^ /newapp {
proxy_pass http://127.0.0.1:6002;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
The problem is that the new app is trying to serve files out of /newapp, which is breaking. I'm thinking it's probably something in my app.js file to play around with Express in the new app, to set the base directory as /newapp/ - to serve both static files and routes from there. Any ideas on how to do this?
In the newapp, I'm serving static files as such:
// Serve files out of ./public
app.use(express.static(__dirname + '/public'));
and have route files as:
var index = require('./routes/index');
app.use('/', index);
with index routing file:
var express = require('express');
var router = express.Router();
// Get index page
router.get('/', function(req, res, next) {
res.render('index', {
index : 'active'
});
});
module.exports = router;

First of all, don't use regexp location if you no need it. Use simple location. And about your question - put / at the end of proxy_pass URI. Nginx will rewrite /newapp/xxx to /xxx and vice versa (for http redirects, for example). But (!) will not rewrite links in HTML body.
location /newapp/ {
proxy_pass http://127.0.0.1:6002/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}

Related

Cannot GET etc with Nginx Reverse Proxy React + Node + PM2

In setting up an Nginx reverse proxy for both a React app and a Node web server, it seems to have broken Express on the backend, although I can tell I'm accessing it in the browser by receiving "Cannot GET XX" messages after adding the second location block soon to follow below (previously the browser was just white when visiting the API endpoints because React Router was trying to grab them).
Here's what the config looks like, where port 3000 is my React app and 4000 is my Express server, both being managed by pm2:
server {
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name www.mywebsite.com; # managed by Certbot
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
location /api/ {
proxy_pass http://127.0.0.1:4000/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
Simple Express route that won't work ("Cannot GET /"):
app.get('/', (req, res) => {
res.send('Hello, world!');
});
There is some additional certbot stuff that was generated for SSL, but I'm not sure it's relevant. The React app works perfectly, but whether it's "location /api/" vs "location /api" and no matter how I name my routes in Express, they all can't resolve despite having worked perfectly before. Thanks in advance for any guidance!
EDIT: I changed the server conf to at least map /api/ to my server's root with a trailing backslash so I don't have to prepend /api to every route handler, but the issue still remains ("Cannot GET /").
Why do you use the following headers?
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
Probably not needed if you are using TLS/https and it may be causing issues with express if the upgrade header exists. Try removing that.
These headers are generally used for WebSockets. See the nginx docs for more details.

404 on POST and GET requests for Node.js app behind NGINX reverse proxy

I have an Ubuntu web server running with this structure:
Nginx reverse proxy localhost:80, which redirects to either '/' (apache server with WordPress site at localhost:8080), which currenly works.
More recently a I've tried to add a Node.js Application at www.site.com/app or, internally, localhost:3000. I am able so serve the HTML and CSS of the node.js webapp, however all internal route calls at 404ing, likely because of the URL addressing of /app/.
IE. Tries to hit /someendpoint and 404s because Node.js is technically running on localhost:3000 (www.site.com/app). Should I be routing arguments like (www.site.com/app/someendpoint)?
The Problem: All POST/GET calls from NODE.JS are 404ing because of my bad understanding of NGINX config. How do I route this GET calls to the actual location of the Node.js server which is (site.com/app/, localhost:3000).
Here is my 'default' config from /etc/nginx/available_sites/.
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
index index.php index.html index.htm index.nginx-debian.html;
server_name www.*site*.name;
location / {
proxy_pass http://127.0.0.1:8080$request_uri;
proxy_buffering on;
proxy_buffers 12 12k;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
try_files $uri $uri/ /index.php?q=$uri&$args;
}
#Currenly serving HTML, CSS of site, however node routes 404
location /app/ {
proxy_pass http://localhost:3000/;
}
}
How might I update this NGINX config file to account for node endpoints actively trying to hit the route of my apache site and not the /app real location of the node server?
Any help or ideas would be great, I've been stuck on this issue for a while as part of a personal project.
Thanks!
please remove the try_files statement in the location / block
your location should look like this
.....
location / {
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
Here is a sample app.js file that may offer you some insight into the matter.
var express = require("express");
var router = require("./lib/routes/index");
var app = express();
var port = 3000;
app.use('/app', router);
app.listen(port, function () {
console.log("Listening on port " + port);
});
As for the nginx configuration, I would recommend something along the lines of the following:
# Sample nginx config with 2 upstream blocks
upstream nodeApp {
server 127.0.0.1:3000;
}
upstream apacheApp {
server 127.0.0.1:8080
}
server {
listen 80;
listen [::]:80;
server_name www.domain.com domain.com;
root /var/www/domain;
location / {
proxy_pass http://apacheApp;
}
location /app {
proxy_pass http://nodeApp;
# OR
# try_files $uri $uri/ #backend;
}
location #backend {
proxy_pass http://nodeApp;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
The key part of this is using an external router in your app.js, then using this line: app.use('/app', router);
You may want to also set up nginx to serve static files instead of relying on express.static(). This would also be easy to do by setting up more location blocks like so:
location /app/public {
try_files $uri $uri/ =404;
}
This should work for your purposes. Don't forget to check your configuration with nginx -t.
For more troubleshooting advice, check out this very similar thread: nginx proxy_pass 404 error, don't understand why
The solution that worked with my 404 issue was to add an extra / after my proxy_pass url.

Nginx location not work on digital-ocean

I created two node.js instance on DigitalOcean's Ubuntu machine.
Both listen to localhost, with different ports.
Then test by curl http:\localhost:${port}. Both worked.
Then I added them to /etc/nginx/site-available/default
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
#try_files $uri $uri/ =404;
proxy_pass http://localhost:8837;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
location /app {
proxy_pass http://localhost:9837;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
Only http://${ip_address}:${port}/ worked.
http://${ip_address}:${port}/app return
"Cannot GET /app"
I used express in node.js is it the problem come from?
I don't know where is wrong, here is what I found:
If remove express from node.js and listen port like this:
var http = require('http');
http.createServer(function (req, res) {
...
}).listen(8001, 'localhost');
The /app worked, no error happen.
If use express like this:
const app = express();
app.listen(8001, 'localhost', function() {
...
});
/app will return error.
To resolve this problem I open another port that create another configuration by copy /etc/nginx/sites-available/default ,then link it to /etc/nginx/sites-enabled
sudo ln -s /etc/nginx/sites-available/default2 /etc/nginx/sites-enabled/
and change the port in server{}

Multiple sailsjs applications running on same port

I need to run multiple sails web application on the port and run a small server to route between them by application name.
Using next code, I could route between them by adding application name after the port 3000.
var express = require('express');
var app = express();
var httpProxy = require('http-proxy');
var proxy = httpProxy.createProxyServer();
var app1 = 'http://localhost:1337/',
app2 = 'http://localhost:1338/'
app.all("/app1/*", function(req, res) {
proxy.web(req, res, {target: app1});
});
app.all("/app2/*", function(req, res) {
proxy.web(req, res, {target: app2});
});
app.listen(3000);
This Program make the redirection well but now the problem is that, how i can change the generated links in sailsjs for any file as javascript and css files?
Many thanks
Install nginx
Run your apps on different ports.
On Linux /etc/nginx/sites-available/default (different on Windows, but probably easy to find):
--
server {
listen 80;
server_name apps.dev/1;
location / {
proxy_pass http://localhost:3001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
server {
listen 80;
server_name apps.dev/2;
location / {
proxy_pass http://localhost:3002;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
You can access your apps using: apps.dev/1 or apps.dev/2
For production you can apply any domain addressed to the server.
For local dev just set virtual host to redirect anything from production domain to local nginx.

Serving static files via nginx instead of express

I know there are quite a few threads on this topic, but unfortunately none of them helped me so far. I had an express application and served my static files like this:
app.use(express.static(path.join(__dirname, 'public'), { maxAge: 86400000 }));
Now I'm using nginx aswell and wanted to serve my static content only via nginx, so I commented the line above and added the following to my sites-enabled/default nginx config:
server {
listen 443 ssl;
// certificate, server_Name
location ~^/(images/|img/|javascript/|js/|css/|stylesheets/|flash/|media/|static/|robots.txt|humans.txt|favicon.ico) {
root /path/to/my/project/public/;
access_log off;
expires 24h;
}
}
location / {
proxy_redirect off;
proxy_pass https://127.0.0.1:8443;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Connection "";
proxy_cache_bypass $http_upgrade;
proxy_cache one;
proxy_cache_key sfs$request_uri$scheme;
}
From what I've read so far the first location block should handle the serving of static files (all my static files are located under public). But when I start my application like this I get ERR_TOO_MANY_REDIRECTS. Only once I add the express config from above my site works.
How can I serve static content via nginx correctly?
Does anyone have some guidance on what exactly I'm doing wrong?

Resources