Can't serve node_modules as static on AWS - node.js

I have hosted my node app on a AWS Linux machine.My code is working perfectly on openshift, its serve node_modules as static to access my angular.But in AWS host its doesn't.
var app = express();
app.use('/bower_components/', express.static(__dirname + '/node_modules/'));
var server = app.listen(app.get('port'), app.get('ipaddress'), function() {
// server.maxConnections = 2;
console.log('Express server listening on port ' + server.address().port);
});
Whats wrong with my code?

After long Re-search I found a solution that I have to forward reqest from nginx to nodejs , nginx will serve them as it exported by node.
I added my site config on /etc/nginx/sites-available/my-site
server {
listen 80;
server_name mysite.com;
location / {
proxy_pass http://APP_PRIVATE_IP_ADDRESS: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;
}
}
Hope this help some one who having this issue.

Related

Websocket (Socket.io) works on my local machine but not on NGINX

I have worked on an application using node.js and express for the backend and reactjs for the frontend.
On the nodejs backend, set up socket.io as such
const port = process.env.PORT || 8000
const server = app.listen(port, () =>
console.log(`Server running on port ${port}`)
)
const io = require('socket.io')(server, {
cors: {
origin: '*',
},
})
Then on the react frontend, I sent up the socket.io for client as:
if (!socket.current) {
socket.current = io(process.env.REACT_APP_API2)
}
Where my REACT_APP_API2='http://localhost:8000' while my api is connected on REACT_APP_API='http://localhost:8000/api'
Locally, this works very well and my websocket connects and works well.
But in production, i get the error wss://+ myDomain + .com:3000/ws connection failed:
This is how I set up my NGINX Server
I first set up this '/' to point to the root (React APP)
location / {
proxy_pass http://localhost: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;
}
NEXT, I Set up /api to point to the backend api
location /api {
proxy_pass http://localhost:8000;
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;
}
Finally, I set this /socket.io for my sockets.
location /socket.io {
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 false;
proxy_pass http://localhost:8000;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
This is how i set up my enviromment variables in my frontend
REACT_APP_API = '/api'
REACT_APP_API2 = '/'
What I have tried:
I have changed the REACT_APP_API2 to '/api'
I have changed the proxy_pass http://localhost:8000; to 3000
NB: my application on nginx is secure ie 'https'

NodeJs App + AWS EC2 + Nginx + Websocket configuration

im running a Nodejs app on a Ec2 instance. The app runs node-rtsp-stream that outputs a websocket witch then uses with jsmpeg to display on the web browser.
NGINX config port 80 (this works fine)
server {
listen 80 default_server;
listen [::]:80 default_server;
location / {
proxy_pass http://localhost: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;
NGINX websocket config (this doesnt)
http {
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream websocket {
server ws://localhost:9999;
}
server {
listen 80;
location / {
proxy_pass http://websocket;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
app.js
Stream = require('node-rtsp-stream')
stream = new Stream({
name: 'stream',
streamUrl: 'rtsp://demo:demo#ipvmdemo.dyndns.org:554/onvif-media/media.amp',
wsPort: 9999,
ffmpegOptions: { // options ffmpeg flags
'-stats': '', // an option with no neccessary value uses a blank string
'-r': 30 // options with required values specify the value after the key
}
})
Script tag on HTML
player = new JSMpeg.Player('ws://localhost:9999', {
canvas: document.getElementById('canvas')
Should this be calling for 'ws://localhost:9999' or something else?. On Browser says that can not find 'ws://localhost:9999'
Each nginx config file is stored in sites-available
Thanks for your time!!!

How can I get visitors IP by Node.js?

I have my own VPS server and I have script in Node.js which display the visitor's IP but always when I visit website I get in console local IP address (127.0.0.1). I use Nginx.
Any idea?
Node.js script:
#!/usr/bin/env nodejs
const http = require('http');
const host = '127.0.0.1';
const port = 8080;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
var ip = (req.headers['x-forwarded-for'] || '').split(',').pop().trim() ||
req.connection.remoteAddress || req.socket.remoteAddress || req.connection.socket.remoteAddress;
console.log(`IP = ${ip}`);
});
server.listen(port, host);
Nginx proxy/headers configuration:
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 / {
try_files $uri $uri/ =404;
proxy_pass http://127.0.0.1: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;
}
}
You need to rig your nginx reverse proxy to pass along the requester's IP address. Adding these two settings to nginx.conf does the trick.
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
Put these lines in your location{...} stanza of nginx.conf along with your proxy-pass and the rest.
With these changes, nginx inserts two http headers into each request: X-Forwarded-For and X-Real-IP. (There's a new standard Forwarded: header, but nginx doesn't handle it easily as of mid-2020.)
Then, use app.set() to add proxy server support to your nodejs program to interpret those headers. Put this line in your www or http-server.js Javascript program shortly after your const app = express() line.
app.set( 'trust proxy', 'loopback' )
Express will then muck around with the X-Forwarded-For header for you and put the appropriate IP address in req.ip.
I've linked to some documentation. You would be wise to read it.

Timeout with socket io

I have an application using socket.io with Node and Express. I'm also using AWS EC2 and Nginx.
I'm getting a timeout with socket io.
The error is:
GET https://vusgroup.com/socket.io/?EIO=3&transport=polling&t=MnUHunS 504 (Gateway Time-out)
Express file:
var port = 8090;
host = 'https://18.237.109.96'
var app = express(host);
var webServer = http.createServer(app);
...
// Start Socket.io so it attaches itself to Express server
var socketServer = socketIo.listen(webServer, {"log level":1});
//listen on port
webServer.listen(port, function () {
console.log('listening on http://localhost:' + port);
});
Nginx file:
server {
listen 80 default_server;
listen [::]:80 default_server;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
proxy_pass http://18.237.109.96:8090/;
}
}
server {
server_name vusgroup.com www.vusgroup.com; # managed by Certbot
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
...
ssl stuff
...
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
proxy_pass http://18.237.109.96:8090/;
}
location /socket.io/ {
proxy_pass http://18.237.109.96:3000;
proxy_redirect off;
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-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
I've tried chaning the proxypass for socket.io to http://18.237.109.96:8090; but that gave me a 400 error.

How do I setup NGINX with a reverse proxy to port 80 for two apps that both need socket.io?

I've been going around this for a couple few days now. I get so close and then a connection seems to die or socket.io cannot be found. But then maybe I'm doing it wrong?
My NGINX files looks something like this:
upstream appOne {
server demo.someserver.com:1111;
}
upstream appTwo {
server demo.someserver.com:2222;
}
location /appOne/ {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://appOne/;
}
location /appTwo/ {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://appTwo/;
}
location /socket.io/ {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://appOne/socket.io/;
}
So what I'm trying to do here is have appOne running in a subfolder at demo.someserver.com/appOne and have appTwo running in a subfolder at demo.someserver.com/appTwo but both have a reverse proxy.
All connects great except both apps need socket.io to run and shouldn't really need to connect to each other (Although I'm starting to think this wouldn't be a bad idea). But at the moment they both connection to appOne/socket.io/socket.io.js because of the last NGINX location. This causes all sorts of problems when connecting like the socket connection not being on the same port etc.
What I'm trying to avoid is naming the ports and the app name inside any frontend JS files as appOne and appTwo in this context could be clientOne and clientTwo.
I did think of something like this:
if ($request_uri == 'appOne') {
proxy_pass http://appOne/socket.io/;
}
if ($request_uri == 'appTwo') {
proxy_pass http://appTwo/socket.io/;
}
But I have no idea how that actually works. Any pointers or has anyone tried to do something the same?
So my question is - how can I have separate connections to socket.io through the reverse proxy. Or should I have one socket.io connection and both attach to that? (but I could have multiple clients on one server)
If you need two separate socket.io apps, you can perform this by setting (undocumented) path option when initializing socket.io on the client.
To be consistent, I will provide you full working example of Nginx config and Node files:
nginx config:
upstream appOne {
server demo.someserver.com:1111;
}
upstream appTwo {
server demo.someserver.com:2222;
}
server {
listen 80;
server_name demo.someserver.com;
root /path/to/working/dir; #probably not necessary
location /appOne/ {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://appOne/;
}
location /appTwo/ {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://appTwo/;
}
# no need for /socket.io location
# each app will connect socket.io via /appOne/socket.io or /appTwo/socket.io
}
app1.js and app2.js (Express + Socket.io example):
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
var port = 1111; //or 2222 for app2.js
app.get('*', function(req, res) {
res.sendFile(__dirname + '/index1.html'); //or index2.html for app2.js
});
io.on('connection', function(socket) {
socket.emit('hello', {port: port});
});
server.listen(port);
index1.html and index2.html:
<!DOCTYPE html>
<html>
<head>
<script src="/appOne/socket.io/socket.io.js"></script>
<!--<script src="/appTwo/socket.io/socket.io.js"></script>-->
<script>
var socket = io('/', {path: '/appOne/socket.io'});
//var socket = io('/', {path: '/appTwo/socket.io'});
socket.on('hello', function(data) {
console.log(data.port);
});
</script>
</head>
<body>
<h1>app</h1>
</body>
</html>
So if you launch both app1.js and app2.js and navigate to
http://demo.someserver.com/appOne
and then
http://demo.someserver.com/appTwo
you will see in your console 1111 and 2222 respectively, which means that you have two independent socket.io apps.
You can set a custom path to socket.io in your script.
Sets the path v under which engine.io and the static files will be
served. Defaults to /socket.io.
If no arguments are supplied this method returns the current value.
Source: http://socket.io/docs/server-api/#server#path%28v:string%29:server

Resources