how to setup nginx reverse proxy for nodejs - node.js

I tried a lot for this, but not working.
help me any one please..
node is at port 3000 and nginx is at 8080 in localhost
this is node index
var express=require('express'),app=express(),cors =require('cors');
app.use(cors({origin: 'http://127.0.0.1:8080'}));
app.get('/home', (req, res) => {res.send("ok");});
app.listen(3000, '127.0.0.1', function(){console.log('listening on port 3000..');});
this is nginx conf
#user nobody;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
server {
listen 8080;
server_name 127.0.0.1;
location / {
root D:/www;
index index.html index.htm;
}
location /api/ {
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;
}
}
}
If i use from frontend jQuery
http://127.0.0.1:8080/api/home
it's not working
if i use from frontend jQuery
http://127.0.0.1:3000/home
it's working
this is the error getting in IE,
HTTP404: NOT FOUND - The server has not found anything matching the requested URI (Uniform Resource Identifier).
(XHR)GET - http://127.0.0.1:8080/api/home

server name in nginx conf is not correct. Server names are defined using the server_name directive and determine which server block is used for a given request. They may be defined using exact names, wildcard names, or regular expressions. Replace it with localhost.
For more info read here.

Related

Websocket connection on Google Compute Engine using a custom domain name

I have a websocket server (node.js) which runs fine on localhost and on a previous heroku deployment. I am now migrating to google compute engine and running into some issues.
The websocket handshake is failing returning a 301 error. As pointed out in this answer this can be due to the request going through front end servers that do not support a websocket connection and can be worked around by targeting ws://my_external_gce_ip directly. I am wondering if there is some load balancing configuration I can update so that I can address my backend using the custom domain name.
While I understand the problem, it seems to me that the domain should be resolved to the external ip after a dns lookup so I don't understand the constraint really.
Sorry if this is very obvious. I'm new to GCE and have been googling all day trying to get this. I will paste my code below as well as the NGINX config but I don't think either are particularly helpful as all works fine addressing using the IP
index.js:
/* requirements */
var bodyParser = require("body-parser");
const WebSocket = require("ws");
const http = require("http");
const express = require("express");
const port = process.env.PORT || 3000;
/*
server definition and config
*/
const app = express();
app.use(bodyParser.json());
const server = http.createServer(app);
/*
web socket stuff
*/
const webSocketServer = new WebSocket.Server({
server,
});
webSocketServer.on("connection", (webSocket) => {
console.log("board trying to connect...");
webSocket.on("message", (data) => {
webSocketServer.clients.forEach((client) => {
if (client === webSocket && client.readyState === WebSocket.OPEN) {
client.send("[SERVER MESSAGE]: You are connected to the server :)");
}
});
});
});
/*
activate server
*/
server.listen(port, () => {
console.log(`Server is now running on port ${port}\n`);
});
nginx config
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name _;
location \ {
# we're actually going to proxy all requests to
# a Nodejs backend
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;
# I added this baby in
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
server
{
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name my_domain; # managed by Certbot
location / {
# we're actually going to proxy all requests to
# a Nodejs backend
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;
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/my_domain/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/my_domain/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server
{
if ($host = my_domain) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80 ;
listen [::]:80 ;
server_name my_domain;
return 404; # managed by Certbot
}
Thanks very much in advance and sorry if this is a noob question. Total noob when it comes to load balancing
Solved. After a lot more googling I found this thread of people facing the same problem most either using apache servers or elastic beanstalk so not using nginx.
It seems that a lot of people get websockets to "work" using socket.io but they don't really have a duplex connection as it is falling back to long polling.
In my case the answer was simple, I didn't include the server name in my nginx (facepalm) and I may have forgot to include a header. The https forwarding now looks like this (and addressing using my domain works)
location / {
# we're actually going to proxy all requests to
# a Nodejs backend
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;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 90;
}
Don't forget to restart your nginx after you update
sudo systemctl restart nginx

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.

Node.js+Nginx throwing 502 bad gateway error

I just installed Node.js application to dev environment. Configuration is :
Ubuntu 16.x
PHP 7.0
Node.js 8.x
Mysql
PhpMyAdmin
Nginx
My node app is using port 2000 and the subfolder name is nodeapp. Though phpmyadmin is opening properly, Node app is giving 502 Bad gateway.
Here is the nginx conf file :
server {
listen 80 default_server;
listen [::]:80 default_server;
listen 2000;
root /home/pjsp/public_html;
index index.php index.html index.htm index.nginx-debian.html app.js;
server_name mydomain.com;
location /nodeapp {
proxy_pass http://localhost/nodeapp:2000;
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 ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}
Below is the error I am getting at /var/log/nginx/error.log file:
2018/06/02 13:13:15 [error] 32209#32209: *763 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: 127.0.0.1, server: mydomain.com, request: "GET /nodeapp:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000
Please help!
Update:
New Config file:
server {
listen 80 default_server;
listen [::]:80 default_server;
#listen 2000;
root /home/pjsp/public_html;
index index.php index.html index.htm index.nginx-debian.html app.js;
server_name app.pajasa.com www.app.pajasa.com;
location /nodeapp {
proxy_pass http://localhost;
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 ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}
Now getting error :
2018/06/02 14:52:35 [alert] 3026#3026: *765 768 worker_connections are not enough while connecting to upstream, client: 127.0.0.1, server: app.pajasa.com, request: "GET /nodeapp:2000 HTTP/1.1", upstream: "http://127.0.0.1:80/nodeapp:2000", host: "www.app.pajasa.com"
url : www.app.pajasa.com/nodeapp:2000
You have an infinite loop inside your nginx. that's why you see:
/nodeapp:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000:2000....
If your Node app, is listening on port 2000, don't use listen 2000; on Nnginx.
And after you drop that, request to: http://localhost/nodeapp will be passed onto your node app.
Furthermore, your proxy_pass is incorrect, it should be:
proxy_pass http://localhost:2000;
UPDATE
Your URL is wrong
www.app.pajasa.com/nodeapp:2000 // INCORRECT
First of all as we already mention, if you're using Nginx to proxy to your Node.js APP, you don't have to add the port on the URL, secondly and more important is that isn't how ports work:
www.app.pajasa.com:2000 // This is correct
Drop :2000 from the URL, Nginx will proxy it to your node app.
www.app.pajasa.com/nodeapp
proxy_pass http://localhost:2000/nodeapp;
Your URL scheme is wrong, its always PROTO://DOMAIN:PORT/PATH
listen 2000;
Your nginx should not listen to the app port. In this case the nginx is calling it self recursively.

502 Bad Gateway in node + nginx proxy setup on Heroku

I'm using this buildpack to serve static files on Heroku with a node + nginx setup. While static assets are served properly, trying to serve content through node results in a 502 Bad Gateway. Node on its own works fine and so does nginx. The problem is when the two need to work together which I guess is because I haven't configured the nginx upstream settings right.
Here's my nginx conf:
worker_processes 1;
error_log /app/nginx/logs/error.log;
daemon off;
events {
worker_connections 1024;
}
http {
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
gzip on;
upstream node_conf {
server 127.0.0.1:<%= ENV['PORT'] %>;
keepalive 64;
}
server {
listen <%= ENV['PORT'] %>;
server_name localhost;
location / {
root html;
index index.html index.htm;
proxy_redirect off;
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_set_header Connection "";
proxy_http_version 1.1;
proxy_pass http://node_conf;
}
location ~* ^.+\.(jpg|gif|png|ico|css|js|html|htm)$ {
root /app;
access_log off;
expires max;
}
location /static {
root /app;
index index.html index.htm;
}
}
}
.
My _static.cfg:
SERVER_TYPE="nginx"
BUILD_WEB_ASSETS="true"
.
My node server:
var app = require( 'express ')()
app.get( '/', function(req, res) { res.send( 'This is from Node.' ) })
app.listen( process.env.PORT )
.
I also have a sample html file in /static to test if nginx works:
<html>This is from nginx.</html>
.
With this config, appname.herokuapp.com should display "This is from Node." but instead I get the 502.
appname.herokuapp.com/static displays "This is from nginx" as it should, so no problems with nginx and static content.
I have tried every combination of values for upstream in nginx server settings but none have worked. What else can I try to make nginx proxy requests to node?
Here's my Heroku Procfile in case it helps: web: bin/start_nginx
I am not really familiar with Heroku, and pretty new to Nginx, but I'll give it a shot: To me it looks like the Nginx-config is saying that Nginx and the node.js app are using the same port (<%= ENV['PORT'] %>).
What you want is Nginx to listen to incoming connections (usually port 80), and have it forward them to the node.js app. Here is an example Nginx config:
# the IP(s) on which your node server is running. I chose port 4000.
upstream xxx.xxx.xxx.xxx { #Your IP adress as seen from the internet
server 127.0.0.1:4000; #Your local node.js process
}
# the nginx server instance
server {
listen 0.0.0.0:80; #Have Nginx listen for all incoming connections on port 80
server_name my-site;
access_log /var/log/nginx/my-site.log;
location / {
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://xxx.xxx.xxx.xxx/; #Your IP adress as seen from the internet
proxy_redirect off;
}
}
This config is working for me on a webserver I am hosting in my living-room. Good luck!
Here's a README with information to get nginx and Node.js working together from a project I created a while back. Also included is an example nginx.conf.
As an overview, basically you're just creating sockets with Node then setting nginx to pipe those upstream. I commonly use this when I want to run multiple Node processes and have nginx stand in front of it.
It also includes working with socket.io out of the box, so you can use those to see how to configure your Node instance as well.

nginx proxy pass Node, SSL?

my nginx server is actually proxying my node backend (which listens on port 3000) with a simple:
location /api/ {
proxy_pass http://upstream_1;
}
Where upstream_1 is my node cluster defined in nginx.conf (on port 3000).
I'm gonna have to add SSL over http connections, so I have the following question: do I only need to configure nginx to enable ssl? And it will automatically "uncrypt" the request and pass it uncrypted to Node which will be able to handle it normally? Or do I need to configure Nodejs to support ssl as well?
If you're using nginx to handle SSL, then your node server will just be using http.
upstream nodejs {
server 127.0.0.1:4545 max_fails=0;
}
server {
listen 443;
ssl on;
ssl_certificate newlocalhost.crt;
ssl_certificate_key newlocalhost.key;
server_name nodejs.newlocalhost.com;
add_header Strict-Transport-Security max-age=500;
location / {
proxy_pass http://nodejs;
proxy_redirect off;
proxy_set_header Host $host ;
proxy_set_header X-Real-IP $remote_addr ;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for ;
proxy_set_header X-Forwarded-Proto https;
}
}

Resources