404 - from nginx application to remote servers localhost? - node.js

I am new to react, and wanted to deploy a site to my domain with Nginx. I need to make the application to be able to fetch from client side, to the localhost of the remote server hosting the site with Nginx. I know exposing this many details might make security experts and hackers either drool or shake their heads. But I am losing my sanity from this.
This is a filtered version of my Node.js express service running on the remote server:
const express = require("express")
const cors = require("cors")
const app = express();
const PORT = 1234;
const spawn = require("child_process").spawn;
app.use(cors())
app.listen(PORT, function(){
console.log(`listening on port:${PORT}...`)
})
app.get("/api/play/:choice", function(req,res){
pythonProcess = spawn('python',["./script.py", req.params.choice]);
pythonProcess.stdout.on('data', function(data) {
res.status(200).send(data.toString('utf-8'))})
})
this is how I am fetching from the deployed react application. The public IP of the droplet I am using
fetch(`104.248.28.88/1234/api/play/rock`)

Change the fetch to replace the / with a : to indicate port, rather than directory
fetch("104.248.28.88:1234/api/play/rock")

Related

Express-Socket.IO App isn't working with my Azure WebApp

For educational purposes I try to deploy an Express Server that is using Socket.IO. The Server should be able to deliver a static HTML Site that was built with React, answer with a "Hello Azure!" message whenever I make a GET Rest Call to http://localhost:4000/api/azure and whenever a new client connects to the site, all the other clients get a message announcing the new client.
const path = require('path');
const express = require('express');
const app = express();
const server = require('http').createServer(app);
const io = require('socket.io')(server);
const router = require('./api/azure');
const PORT = process.env.PORT || 4000;
io.on('connection', () => {
console.log('A new user has connected!')
io.emit('broadcast', 'A new user has connected');
});
app.use(express.json());
app.use('/api/azure', router);
app.use(express.static(path.join(__dirname, 'build')));
app.use(express.static('public'));
app.use('/', (_, res) => {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
server.listen(PORT, () => {
console.log(`Listening to http://localhost:${PORT}`);
});
All this tasks are fulfilled without problems in localhost. The problem begins after this app is uploaded to one of my Azure WebApps.
Instead of delivering the message "Hello Azure!" when I call the https://mydomain.azurewebsites.net/api/azure it responses back with the HTML file.
The typical Socket.IO GET method for polling
https://mydomain.azurewebsites.net/socket.io/?EIO=4&transport=polling&t=SomeString
responses back with the HTML file, too.
Everything url extension that I give, gives me back the HTML file.
I barely know the basic stuff about WebApps. Maybe there is a configuration that I am forgetting? By the way I haven't done anything in the configuration except that I enabled the Websockets in the WebApp config.
This never happened before. The only difference is that right now I am using a free-tier just to test. Could it be that? If not, what am I doing wrong?
Thank you for your time!
To begin with, try turning the Web Socket config off as it applies to an IIS setting which tends to contradict with the Node.js websocket implementation.
If this doesn't help, try and force the transport layer to use Websockets and SSL.
io.configure(function() {
// Force websocket
io.set('transports', ['websocket']);
// Force SSL
io.set('match origin protocol', true);
});
Also, you cannot use arbitrary ports (port 4000 in your case) on services like App Service. Your app will be provided a port via process.env.PORT. So ensure that you are refering to the correct port from your log message. You should be able to see these in your log stream.
Also note, that Azure has launched a fully managed service called Web PubSub to power your apps with Web Sockets. The app service web socket implementation does not scale horizontally, this where Web PubSub will help you.
https://azure.microsoft.com/en-in/blog/easily-build-realtime-apps-with-websockets-and-azure-web-pubsub-now-in-preview/

Unable to run Nodejs app on AWS Beanstalk

I have deployed NodeJS app on AWS Beanstalk. I am using AWS code pipeline for deployment from Github. After deployment when I am visiting URL, it's showing below error on web page:
502 Bad Gateway
nginx/1.18.0
Below is my basic node code:
const express = require('express');
const app = express();
const port = 3000 || process.env.PORT;
app.get('/',(req,res) => {
res.send("Hello there");
});
app.listen(port,(req,res) => {
console.log(`App is running at ${port}`);
});
In below screen health of my environment is also showing severe. How can I resolve this?
Your load balancer needs a part of your application to "ping" which is sometimes called a heart beat or just a 'health check'.
This is usually just something that returns a HTTP 200 response to let the load balancer know that the host is healthy and can receive traffic.
I'm not a node.js guy but if you can create some endpoints like /health-check and just return an "ok" or HTTP 200 that will satisfy the need.
You can also have your health-check do something like check if the database connection is running as well. It's up to your specific use case.
Within beanstalk you would then designate /health-check as the URL endpoint for the load balancer to check.
Check out this link as well:
https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/using-features.healthstatus.html
This is the logic error => const port = 3000 || process.env.PORT;
Try with this assignment => const port = process.env.PORT || 3000;

Socketio won't connect from hosted site to droplet

I have a digital ocean droplet that is running a nodeJS server being run with pm2. When I run my preact app locally with the io.connect set to
io.connect('app.ardilabs.com:9080');
app.ardilabs.com is where the nodeJS server lives.
The locally run web app will connect to the remote server from D.O. and then will update my app with the data I am POSTing using Postman.
When I try to build the app and put it on the same D.O droplet and serve the app using nginx the app will load when you go to the URL but it won't connect to the nodeJS server. When I try to POST something I get a confirmation from the server that it got my data but it's never forwarded to the app.
Why does it work locally and with a remote server but not when I am hosting the app and serving it with nginx? I am really stumped.
Here is the relevant server code:
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies
// routes will go here
io.on('connection', function(socket){
//We need a connection but we don't need to do anything about it
});
// start the server
http.listen(9080, function() {
console.log('listening on *:9080');
});
Here is the relevant client code:
import io from 'socket.io-client';
const socket = io.connect('app.ardilabs.com:9080');
A few extra notes:
I am using nginx as my web server
My site has a cert from Let's Encrypt
If I am missing any info needed please let me know!
I figured out what the issue was.
Once I put a cert on my nginx server I didn't realize that I needed to configure my express server to also use HTTPS. Once I enabled HTTPS on the express server the data went through to the connected web app just fine.

Trying to proxy with Node and express-http-proxy and failing

I'm launching NPM express in a very simple app and wanting to take what is passed into the URL and redirect it as follows. Assuming I'm listening for web traffic on 8080 and I want to proxy my rest calls to port 5000.
That is, when the URL http://localhost:3077/rest/speakers comes in, I want the results to come from http://localhost:5000/rest/speakers (where the word speakers could be sessions, attendees or any other name like that.
app = express();
app.use('/rest', proxy('http://localhost:5000/rest'));
app.listen(8080, function () {
console.log('Listening on port 8080');
});
I seem to get the result of localhost:5000 but not even sure of that.
I changed to using http-proxy-middleware and this solved my problem.
app = express();
const proxy = require("http-proxy-middleware");
const targetVal = 'http://localhost:5000/rest';
app.use(proxy('/rest', {target: process.env.DEV_RESTURL, changeOrigin:true}));

Between Node.JS and Express, can someone explain where the Web Server fits in?

I've recently started server-side development using Node JS and Express but i'm getting confused as to how it all works. From my understanding, The web serve stores the website and returns the pages as they're requested from the browser. Apache is a web server and you would use that for a stack like XAMPP. ASP.NET is a framework that uses IIS Web Server and communicates with that.
But with Node, where's the server? Node is runtime environment and is USED to CREATE a server and Express is a web FRAMEWORK to help with server http requests but what/where is the actual web SERVER? Maybe i'm just not understanding web servers or something? Someone please clarify!
For Node, we do not need a web server like Apache or a container that sort of, node can listen to a port and act as a server itself,
and express is web application framework for Node which provides set of features to make life easier.
for a vague comparison, if Node is a telephone then Node + express will be a smartphone. - both can do same stuff but latter have more convenient features.
see below two example of creating a server which listen to a port 3000,
In node:
const http = require('http')
const requestHandler = (request, response) => {
console.log(request.url)
response.end('Hello Node.js Server!')
}
const server = http.createServer(requestHandler)
server.listen(3000,() => console.log("app started"));
Node + express
const express = require('express');
const app = express();
app.get('/', function (req, res) {
res.send('Hello express !')
})
app.listen(3000,() => console.log("app started"));
Both does the same thing, but with express things are easier.

Resources