Formatting node apps for AWS deployment - node.js

I'm trying to deploy a node.js app on aws EC2 Beanstalk. My problem is, I can't figure out how to move from my localhost testing environment to aws standard. Right now, my app works on port 8081 by using the following code.
var server = app.listen(8081, function () {
var host = server.address().address
var port = server.address().port
})
How would I change this server variable to work on an actual domain?

Assuming your intent is to provide a public-facing web application, your code will work as is, albeit with a few caveats:
Currently your server will listen on port 8081. Once deployed to AWS users would have to browse to www.somedomain.com:8081 to reach your application. (Assuming the host instance allows traffic on that port. See below).
If your intent is to have users reach your application at www.somedomain.com - without specifying a port - you'll want the server to listen on port 80 instead.
var server = app.listen(80, function () { ... }
In either case you'll need to ensure that the security group rules for the EC2 host instance allow incoming TCP traffic on the listening port. Likewise, if your EC2 host instance is behind a load balancer you'll need to allow incoming traffic on the appropriate ports there as well.
For something a little fancier, you can try deploying your application to Elastic Beanstalk using Docker and exposing port 8081 in the dockerfile. This way users would still reach it at www.somedomain.com (via http port 80) and you could continue to develop and test locally using port 8081.
One final note: you didn't provide much information about what your application is or how you intend to use it, so I'm making quite a few assumptions based only on the information provided.

This code works great for me with node on Elastic Beanstalk, and allows me to seamlessly switch between localhost and remote development without changing any code:
var port = process.env.PORT || 8081;
var server = app.listen(port, function () {
//server is started!!!
})

Related

How to use Express and GRPC in same service on Google Cloud Run without hitting Port Conflict

I have a NodeJS micro-service hosted on Google Cloud Run.
The service houses both an express server for user facing routes and a gRPC server for communicating with other internal micro-services.
Below is my code so far:
....
//For the express server I am using an hard coded port because of port conflict with grpc server port
const app = express();
const hardCodedPort=3000; //I can't use process.env.PORT here because grpc server below needs it
app.listen(hardCodedPort);
......
//For grpc I am NOT using an hardcoded port, I am listening to the port provided by Cloud Run as shown below
gRPCServer.bindAsync(`0.0.0.0:${process.env.PORT}`, grpc.ServerCredentials.createInsecure(), () => {
gRPCServer.start();
});
Now, owing to the fact that Cloud Run can spin very many instances of the above service will I hit a port conflict for my express server since it is always listening on an hard coded port?
The Cloud Run Frontend (GFE) only supports two ports: 80 and 443. If a client connects to port 80, the client will be redirected to port 443. In other words, your Cloud Run service can only support one internal port number, which defaults to 8080 (configurable). Your application can only listen for connections on one port.

heroku send request from a front-end app to a back-end one

I created an hapi.js backend app on heroku. After a bunch of problems all works well. Now, I want to create a frontend app with react.js, but I have a problem:
const server = Hapi.server({
port: process.env.PORT,
host: '0.0.0.0'
});
To define the port of the backend I've the enviroment variable, so I don't really know its value. So how can the react app knows the correct port of the server where to connect?
You actually don't need to know the port number. You can use the default port which is 80 for HTTP and 443 for HTTPS.
According to the heroku docs:
The contract with Heroku is for the process to bind to a port to serve requests. Heroku’s routers are then responsible for directing HTTP requests to the process on the right port.
Which means heroku listens to port 80 for HTTP and port 443 for HTTPS by itself.
References:
https://devcenter.heroku.com/articles/runtime-principles#web-servers
https://stackoverflow.com/a/51572239/5045878
https://stackoverflow.com/a/54200996/5045878
I would say you don't need to know the port because all your requests will be done to https://hapi.yourdomain.com, and your front will be served to https://yourdomain.com
Edit:
In heroku this is how you define the port:
const port = process.env.PORT || 8000
Heroku will provide the environment variable you need (that changes every time you deploy your app)
Then your react app don't need to connect to a specific port, just access your endpoints like this :
https://back.domain.com/your/endpoint

Making my Node app accessible to the Internet from a local machine

OK so I know I can use cloud hosting and I've done so before but I am doing a demo and I want my node app to be on my local machine but accessible from the internet. Here is how I start the server in the server file
const port = 8080;
var server = http.createServer(app).listen(port, () => {
console.log(`Server listening on port ${port}`);
});
Next I set up port forwarding on my Xfinity gateway such that both port 80 and port 8080 point to my desktop. I know I am connecting to the right device because SSH works from outside of my network on port 22. However when I enter [public IP]:8080 I am unable to receive a response. The only time I receive a response is when I enter 10.0.0.58:8080 which refers to my internal network. Why is this???
I personally like ngrok to do the same thing. It's really easy to setup and I found it really stable.
Give it a go https://ngrok.com
After installing you can simply forward ports like
ngrok http 8080

AZURE + SOCKET.IO: How do I know which port my Web App is using?

I went to a Hackathon last weekend and a Microsoft recruiter set me up with Azure for my Node.js project.
We used Socket.io with my project and had a hard time connecting the Client to the Server because we didn't know which port to connect to...
On our WebApp (not Azure VM), we had the following code:
var port = process.env.port || 3000;
On the client side of Socket.io, I had to specify an ip address to use along with it's port. I tried:
var socket = io('http://IP.AD.DRE.SSS:3000'); //And
var socket = io('http://IP.AD.DRE.SSS'); //And even a different Port
var socket = io('http://IP.AD.DRE.SSS:9999'); //And 443 and 80
And every iteration... I had to be doing something wrong. We ended up switching over to Digital Ocean because I knew how to use it but I really wanted to get this working.
Any Ideas?
UPDATE:
I changed it to 80 and my current error is: "Access Control Allow Origin." Note: My client is running on a server.
UPDATE 2: Return of the OP
Unfortunately, the CORS package for Node did not do the trick...
Some more info:
I'm not using Express or Connect. My server is on Azure (as an Azure Web App). My Client was on Localhost (Thanks to WebStorm).
Azure Web Apps only listens on ports 80 & 443. Change the port to either of them and your app will work fine.
Just leave the port off in the client string. You can connect using the URL alone. Look at my code I codefoster.com/commandmonkey as an example.

node.js hosting with SSL?

So say I have a node.js application that hosts both a HTTP and HTTPS server as described in the question: How to force SSL / https in Express.js
In my code I have the following:
// General configuration settings for production usage
app.configure(function () {
app.set('port', process.env.PORT || 3000);
app.set('sslport', process.env.SSLPORT || 4000);
...
}
http.createServer(app).listen(app.get('port'), function () {
winston.info('Express server listening on port ' + app.get('port'));
});
var options = {
key: fs.readFileSync('key.pem'),
cert: fs.readFileSync('cert.pem')
};
https.createServer(options, app).listen(app.get('sslport'), function () {
winston.info('Express server listening on port ' + app.get('sslport'));
});
Which works perfectly fine for a local running node server.
However, I want to publish my site to a cloud hosted provider like Azure Web Sites, Heroku, Nodejitsu, etc.
All of the cloud hosts seem to set a process.env.PORT value, but only the one. When my HTTPS server is created this usually results in the app crashing, as the PORT is already in use / access denied / etc.
So how do I create / host a site with a secure login page with only one port to work with!?
If you use Heroku you get SSL without needing to specify a port in nodejs. All you need to do is listen on the heroku PORT environment variable for http requests. Once uploaded to heroku you can address your heroku app using either https (on 443) or http (on port 80). Heroku routes either to your server.
Similarly if using elastic load balancing with EC2 you can make use of SSL termination at the load balancer, and again route to your node server listening on port 80 using using http. http://aws.amazon.com/elasticloadbalancing
In both cases you can use either self-signed or proper SSL certificates depending upon your need.

Resources