Cannot GET / Node JS Amazon EC2 server issues - node.js

In my app.js file
app.listen(process.env.PORT || 8080, () => console.log(`Listening on port ${process.env.PORT || 8080}!`));
In my webpack.config.js file
devServer: {
port: 3000,
open: true,
proxy: {
'/api': 'http://localhost:8080'
}
}
In /etc/nginx/sites-enabled/default on my EC2 instance
server {
listen 80;
server_name _;
location / {
proxy_pass http://[private ip]: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;
}
}
EDIT: Full app.js file
const app = express();
app.use(cors());
app.use(express.static('dist'));
app.listen(process.env.PORT || 8080, () => console.log(`Listening on port ${process.env.PORT || 8080}!`));
app.post('/api/[route]', async (req, res, next) => {
try {
const seq = await sequelize();
const file = await [...];
} catch (err) {
return next(err);
}
});

The correct config was
server {
listen 80;
server_name _;
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;
}
}
I believe i had installed pm2 incorrectly at the beginning, because both the nginx server and pm2 were trying to listen on port 80. So i did a fresh install of everything, and voila it works now.

Related

Using Nginx as proxy for Node.js' Express and Socket.io

I want to run an express server and a socket.io server on an node.js instance which are reachable through nginx. If possible, I would favor to run them both on the same port, but I did not reach that goal either.
I can reach the webserver locally and from extern.
I can only reach the socket server locally.
When I call the page, my browsers log shows the following error:
GET https://example.com/socket.io/?EIO=3&transport=polling&t=O6qCW5Y
400 Bad Request
So I think the problem lies somewhere in the nginx config.
My app.js code for the socket.io server:
const http = require('http').createServer();
const io = require('socket.io')(http);
http.listen(3001, () => {
console.log('Socket-Server listening on port: 3001');
});
io.on('connection', (socket) => {
...
});
My code for the client:
window.onload = function() {
const socket = io.connect('https://box-api.com/');
socket.on('connect', () => {
...
}
}
My nginx config:
server {
server_name example.com;
root /nodejs/example.com;
include static_files.conf;
index app.js;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
}
location /socket.io {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:3001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
# Certbot stuff
...
}

WebSocketClient.js:16 WebSocket connection to wss://mydomain.com:3000/ws failed: error on nginx

When I run my application on chrome, I get the error. Websocket doesn't work, but it works locally.
this is my nginx server setup. I have 2 server instances. I don't know if that is the problem. Anyone knows the best way to fix this??
server {
listen 80;
server_name mydomain + .com;
rewrite ^/(.*) https://mydomain + .com/$1 permanent;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name mydomain + .com;
ssl_certificate /home/chained.crt;
ssl_certificate_key /home/mykey.key;
// Frontend Setup
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;
}
// API SETUP
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;
}
// SOCKET.IO SETUP
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 my nodejs setup for backend.
const app = express()
const httpServer = https.createServer({}, app)
const io = require('socket.io')(httpServer, {
cors: {
origin: '*',
methods: ['GET, POST'],
credentials: true,
allowedHeaders: ['custom-header'],
},
})
httpServer.listen(port, () => {
console.log(`Server running on port ${port}`)
})
MY react setup looks like this
useEffect(() => {
if (!socket.current) {
socket.current = io(process.env.REACT_APP_API_APP)
console.log('SOCKET', socket.current)
}
if (socket.current) {
socket.current.emit('join', { userId: user._id })
socket.current.on('connectedUsers', ({ users }) => {
users.length > 0 &&
dispatch({
type: 'SET_CONNECTED_USERS',
payload: users,
})
// users.length > 0 && setConnectedUsers(users)
})
}
My application works locally. but on nginx, It doesn't work. I just get the error as shown in the image.
I am new to servers. Any help would be appreciated.

Socket.io Socket.onPacket Error with reverse proxy Nginx

I have a small angular app who comunicate with a node.js server. Both are deployed on aws and I use Nginx reverse proxy to acess the node.js server at the port 4000.
All end-points of the nodejs.server works fine, except the socket.io connection.
When I run both apps (front end app and the node.js server) in my machinine the socket.io connection works fine, but when I try to deploy it on aws I get this error in the front-end app:
Error: server error
at Socket.onPacket (socket.js:401)
at XHR.<anonymous> (socket.js:216)
at XHR.push.dMso.Emitter.emit (index.js:145)
at XHR.onPacket (transport.js:103)
at callback (polling.js:101)
at Array.forEach (<anonymous>)
at XHR.onData (polling.js:105)
at Request.<anonymous> (polling-xhr.js:94)
at Request.push.dMso.Emitter.emit (index.js:145)
at Request.onData (polling-xhr.js:236)
This is my Nginx configuration in /etc/nginx/sites-available/default:
server{
charset utf-8;
listen 80 default_server;
server_name 18.231.153.164;
# angular app & front-end files
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
root /opt/front-end/dist/admin;
try_files $uri /index.html;
}
# node api reverse proxy
location /api/ {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://localhost:4000/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
# node api reverse proxy
location /socket.io {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://localhost:4000/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
As you can see, my node.js is running at port 4000, so everytime someone try to access the web site with the path /api/ it will be redirected to the node.js server.
Here is a piece of my node.js code:
const socketio = require('socket.io');
const express = require('express');
const app = express();
const port = 4000;
const httpServer = app.listen(port, () => {
console.log('Server listening on port ' + port);
});
let io = socketio(httpServer, {
cors: {
origin: "http://localhost:5200",
},
});
// auth moddleware
io.use((socket, next, err) => {
const jwtToken = socket.handshake.query.jwtToken;
// console.log('token --> ', jwtToken);
const user = socket.handshake.query.user;
if (!user) {return};
socket.user = JSON.parse(user);
next();
});
io.on('connection', (socket) => {
socket.emit('messageFromServer', {data: 'Welcome to server'});
})
Here is a piece of my front-end code:
import {io} from 'socket.io-client';
...
// Connect to server (When I am running locally I change '/api' to 'http://localhost:4000'
this.socket = io('/api', {secure: true, reconnection: true, rejectUnauthorized: false, query: {user: user, jwtToken: this.authService.authValue.jwtToken}});
// Listen to events
this.socket.on('usersOnline', (usersOnline) => {
console.log('Users online now:', usersOnline);
});
this.socket.on('connect_error', (err) => {
console.log('ERR::', err);
});
The version of socket.io in the server is "^4.0.0", and the version of the socket.io-client in front and is "^4.0.0".
I believe this issue is related with the reverse proxy and socket.io somehow. As I told before, the socket.io connection works fine in local envoriment.
Can someone please help me?
I found the solution.
I need to add proxy_redirect off; on the socket.io reverse proxy.
location /socket.io {
proxy_pass http://localhost:4000;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
Then I had another problem, in the font end I start to get an error or invalid namespace.
So I change the client connection to / instead od /api:
this.socket = io('/', {query: {user: user, jwtToken: this.authService.authValue.jwtToken}});
Just check and install same version of socket.io and socket.io-client

NGINX config with Node.js Express and TCP server on same port?

I am trying to set up my node server that uses express to serve files on port 3000 and the net library to serve a TCP server on port 5052, so:
const express = require('express');
const app = express();
const httpServer = require('http').Server(app);
const io = require('socket.io').listen(httpServer);
const path = require('path');
const net = require('net');
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, './public/index.html'))
});
let server = net.createServer(function(socket) {
// Left out for brevity
}
server.listen(5052, 'localhost');
httpServer.listen(3000, () => {
console.log('Ready on port 3000');
});
Locally, this all works very well. I can load up localhost:3000 and I get my HTML served and it connects to socket.io fine. I can also connect to the server on port 5052 perfectly and life is good. I just can't get nginx to serve it all correctly. Here's what I have:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name mycoolproject.com www.mycoolproject.com;
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;
}
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/mycoolproject.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mycoolproject.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
if ($scheme != "https") {
return 301 https://$host$request_uri;
}
}
server {
listen 5053;
server_name mycoolproject.com www.mycoolproject.com;
location /{
proxy_pass http://localhost:5052;
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;
}
}
When I navigate to mycoolproject.com I get the site loaded fine, so the express side is working fine. I just can't connect to my server on 5053. Any ideas?
You need to configure a different port for Nginx, 5052 is busy by Node.js.
server {
listen 5053;
server_name mycoolproject.com www.mycoolproject.com;
location /{
proxy_pass http://localhost:5052;
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;
}
}
Then you can connect to mycoolproject.com:5053

Handle Express Subdomain with nginx

I Wonder how can i handle subdomains in my project that based on Expressjs.
Here's My nginx configuration
server {
listen 80;
server_name bee.local;
access_log /var/log/nginx/bee.local.access.log;
error_log /var/log/nginx/bee.local.error.log;
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 X-Forwarded-For $remote_addr;
}
}
server {
listen 80;
server_name api.bee.local;
access_log /var/log/nginx/bee.local.access.log;
error_log /var/log/nginx/bee.local.error.log;
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 X-Forwarded-For $remote_addr;
}
}
and here's my router with subdomain support
router.get('/v1/', function(req, res, next) {
res.status(200).json({ title: "title" });
});
app.use(subdomain('api', router));
The problem is that it's rendering the index route
and for sure i setuped the hosts file
I've been searching for 3 hrs can you help me :)
There are several requirements:
Setup Host header in nginx with required domain or proxy if applicable
Use subdomain middleware before other middlewares that handle endpoints
Work example:
nginx configuration:
server {
listen 80;
server_name bee.local;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
server {
listen 80;
server_name api.bee.local;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
nginx configuration with hardcoded Host header values:
I believe that you did not setup Host header correctly. please try next configuration
server {
listen 80;
server_name bee.local;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
# proxy_set_header Host $host;
proxy_set_header Host bee.local;
}
}
server {
listen 80;
server_name api.bee.local;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
# proxy_set_header Host $host;
proxy_set_header Host api.bee.local;
}
}
express app:
var subdomain = require('express-subdomain');
var express = require('express');
var app = express();
var router = express.Router();
router.get('/', function(req, res) {
res.send('Welcome to our API!');
});
router.get('/users', function(req, res) {
res.json([
{ name: "Brian" }
]);
});
app.use(subdomain('api', router));
app.get('/', function(req, res) {
res.send('Homepage');
});
app.listen(3000);

Resources