Node.js/Express.js App Only Works on Port 3000 - javascript

I have a Node.js/Express.js app running on my server that only works on port 3000 and I'm trying to figure out why. Here's what I've found:
Without specifying a port (app.listen()), the app runs but the web page does not load.
On port 3001 (app.listen(3001)) or any other port that is not in use, the app runs but the web page does not load.
On port 2999, the app throws an error because something else is using that port.
On port 3000, the app runs and the web page loads fine.
I know that Express apps default to port 3000. But strangely, my app only runs when I explicitly make it run on port 3000 (app.listen(3000)).
I found this on line 220 of /usr/bin/express:
app.set(\'port\', process.env.PORT || 3000);
Which is doing as previously stated: setting the port to what is specified or to 3000 if nothing is specified.
How could I make my app work on a different port such as 8080 or 3001?
Thanks!
Edit: Code Sample (Very Simple Node/Express App)
var express = require("express");
var app = express();
app.get('/', function(req, res){
res.send('hello world');
});
// Only works on 3000 regardless of what I set environment port to or how I set [value] in app.set('port', [value]).
app.listen(3000);

The following works if you have something like this in your app.js:
http.createServer(app).listen(app.get('port'),
function(){
console.log("Express server listening on port " + app.get('port'));
});
Either explicitly hardcode your code to use the port you want, like:
app.set('port', process.env.PORT || 3000);
This code means set your port to the environment variable PORT or if that is undefined then set it to the literal 3000.
Or, use your environment to set the port. Setting it via the environment is used to help delineate between PRODUCTION and DEVELOPMENT and also a lot of Platforms as a Service use the environment to set the port according to their specs as well as internal Express configs. The following sets an environment key=value pair and then launches your app.
$ PORT=8080 node app.js
In reference to your code example, you want something like this:
var express = require("express");
var app = express();
// sets port 8080 to default or unless otherwise specified in the environment
app.set('port', process.env.PORT || 8080);
app.get('/', function(req, res){
res.send('hello world');
});
// Only works on 3000 regardless of what I set environment port to or how I set
// [value] in app.set('port', [value]).
// app.listen(3000);
app.listen(app.get('port'));

In bin/www, there is a line:
var port = normalizePort(process.env.PORT || '3000');
Try to modify it.

Try this
$ PORT=8080 node app.js

Try to locate the bin>www location and try to change the port number...

The default way to change the listening port on The Express framework is to modify the file named www in the bin folder.
There, you will find a line such as the following
var port = normalizePort(process.env.PORT || '3000');
Change the value 3000 to any port you wish.
This is valid for Express version 4.13.1

Just a note for Mac OS X and Linux users:
If you want to run your Node / Express app on a port number lower than 1024, you have to run as the superuser:
sudo PORT=80 node app.js

In the lastest version of code with express-generator (4.13.1) app.js is an exported module and the server is started in /bin/www using app.set('port', process.env.PORT || 3001) in app.js will be overridden by a similar statement in bin/www.
I just changed the statement in bin/www.

Noticed this was never resolved... You likely have a firewall in front of your machine blocking those ports, or iptables is set up to prevent the use of those ports.
Try running nmap -F localhost when you run your app (install nmap if you don't have it). If it appears that you're running the app on the correct port and you can't access it via a remote browser then there is some middleware or a physical firewall that's blocking the port.
Hope this helps!

The line you found just looks for the environmental variable PORT, if it's defined it uses it, otherwise uses the default port 3000. You have to define this environmental variable first (no need to be root)
export PORT=8080
node <your-app.js>

If you want to show something you're connected on 3000
var express = require('express')
var app = express()
app.get('/', function (req, res) {
res.send('Hello World!')
})
app.listen(3000, function () {
console.log('Example app listening on port 3000!')
})
I hope that will be helpful to you

Answer according to current version of express
If you talk about the current version of express, if you run app.listen() to start listening without specifying port, Express will chose a random port for your application, to find out about which port it is currently running on use
app.listen(0, () => {
console.log(app.address().port)
}
should output the port of your app. Moreover that first parameter 0 can be totally ignored but is not recommended

In app.js, just add...
process.env.PORT=2999;
This will isolate the PORT variable to the express application.

I am using the minimist package and the node startup arguments to control the port.
node server.js --port 4000
or
node server.js -p 4000
Inside server.js, the port can be determined by
var argv = parseArgs(process.argv.slice(2))
const port = argv.port || argv.p || 3000;
console.log(`Listening on port ${port}...`)
//....listen(port);
and it defaults to 3000 if no port is passed as an argument.
You can then use listen on the port variable.

Make sure you are running from that folder of your application, where you have the package.json.

I think the best way is to use dotenv package and set the port on the .env config file without to modify the file www inside the folder bin.
Just install the package with the command:
npm install dotenv
require it on your application:
require('dotenv').config()
Create a .env file in the root directory of your project, and add the port in it (for example) to listen on port 5000
PORT=5000
and that's it.
More info here

If you are using Nodemon my guess is the PORT 3000 is set in the nodemonConfig.
Check if that is the case.

Related

getting node port is undefined even though i don't see anything listening on the ports

I currently have a node.js backend going with express to serve my routes. I have the port in my .env file as shown below
NODE_ENV = development
port = 7000
Now when I try to run my backend, the port is not available. I run the commands below to check but I don't get any output from the terminal
lsof -i:7000
lsof -i:8080
I am not sure what's holding the ports. I will paste my server.js below for reference also.
import express from 'express'
import dotenv from 'dotenv'
import colors from 'colors'
dotenv.config()
const app = express();
const PORT = process.env.PORT || 8080;
if (!process.env.PORT) {
console.log(`Port is unavailalbe ${PORT}`)
process.exit(1);
} else {
app.listen(PORT, console.log(`Server is running in ${process.env.NODE_ENV} on port ${PORT}`.yellow.bold));
}
You have variable port in .env but you're checking if PORT is defined (which is not). Change port to PORT in .env.
Edit: I also recommend removing spaces in .env.

Is there a way to restart node server in runtime?

I am trying to define an endpoint in my express server that whenever this end point is called, the server restarts automatically in runtime.
for example, using express my server would look something like this ...
var express = require('express')
var app = express();
app.post('/restart', (req,res)=>{
//restart or create a new instance of the server
// then reply
res.json({
'message': 'server restarted successfully'
})
})
// =======================
// start the server ======
// =======================
var port = process.env.PORT || 8000;
app.listen(port);
console.log('server running at http://localhost:' + port);
NOTE: Although I am using expressJS, I am open to other solutions like HAPI for example.
Thanks in advance
The only way I know of how to restart a node instance is in the CLI level via npm forever or the pm2, but this is for deployment level xP.
You would need npm module forever to be globally installed on your system and Shelljs as a dependency. Initially start your server as forever start {Path to server.js}. Then you can do
var express = require('express')
var shell = require('shelljs')
var app = express();
app.post('/restart', (req,res)=>{
//restart or create a new instance of the server
shell.exec('forever restart {Path to server.js}');
// then reply
res.json({
'message': 'server restarted successfully'
})
})
// =======================
// start the server ======
// =======================
var port = process.env.PORT || 8000;
app.listen(port);
console.log('server running at http://localhost:' + port);
Also see that you will not get a response as the server would have restarted. You would just get a refused to connect.
You can use PM2 to start, stop your server using simple commands.
Starting an application in production mode is as easy as:
pm2 start app.js
Stop all apps
pm2 stop all
Restart all apps
pm2 restart all
I hope this will work for you.
HTH Thanks!
Since express uses the HTTP from Node, you might initialize the Express server by yourself with the Node HTTP functions, noted here.
Once you have the server started, you might close it and restart it as you wish, as mentioned here.
Just you have to be careful with the already opened connections, as calling the HTTP instance for close will leave the already opened connection(s) still open. More information about closing them all; can be found here.

Unable to dockerize a nodeapp

Created the docker file as following:
FROM node:boron
ADD package.json package.json
RUN npm install
ADD . .
EXPOSE 4500
CMD ["node","main.js"]
Building the app:
docker build -t "appname"
Running the app:
docker run -it "appname"
Inside main.js, I have:
var express = require("express");
var app = express();
var path = require('path');
var http = require('http');
var https = require('https');
var nodemailer = require('nodemailer');
var bodyParser = require('body-parser');
var request = require("request");
var port = process.env.PORT || 3001;
app.set('port', (port));
app.listen(app.get('port'), function () {
console.log('Node app is running on port', app.get('port'));
});
//app.use('/', express.static(path.join(__dirname, '/public_html')))
app.use('/', express.static(__dirname + '/public_html'));
app.use(bodyParser.json({limit: '5mb'}));
app.use(bodyParser.urlencoded({
limit: '5mb',
extended: false
}));
app.get('/', function(request, response) {
response.render('public_html/');
});
//app.get('/', function (req, res, next) {
// res.sendFile('/index.html');
//});
app.use('*', function (req, res, err) {
// console.log('error: ', err);
});
when I run the app using docker command 'docker run -it "appname"`, I get the out to console:
Node app is running on port 3001
But when I browse, page is empty or nothing is loaded in the browser/output/view. It is supposed to pick up index.html from response.render('public_html/');
You need to explicitly expose the port which your app is supposed to run on:
docker run -p 3001:3001 your-node-image
Then you can access your container's service on your docker host under http://localhost:3001, because -p 3001:3001 binds the host port 3001 (the first 3001 in the argument) to the container's port 3001 (the second 3001).
EXPOSE from your Dockerfile only describes which ports are exposed by your application (which is in your Dockerfile 4500 and in your program port 3001...? Why are they different?). Publishing ports with -p is also necessary to access the container, see the docs:
The EXPOSE instruction informs Docker that the container listens on the specified network ports at runtime. EXPOSE does not make the ports of the container accessible to the host. To do that, you must use either the -p flag to publish a range of ports or the -P flag to publish all of the exposed ports.
Additionally, the flags -it appear to be useless with your service. You need these flags when you want to have an interactive session, e.g. when you're starting a shell in your container.
See here some more information about port exposal in the official documentation

Stuck in Mean Stack

I am new to MEAN Stack. and i am using Ubuntu. i installed ejs, express, node etc via Terminal. i made a folder in Documents>NodeTuts and then in in terminal i wrote npm init after the progress i got package.json in nodeTuts and server.js and than i made a folder in nodeTuts named client and then in client>views and in views i made a file index.ejs.
In server.js i wrote:
var express = require('express');
var app = express();
var path = require('path');
var port = process.env.PORT;
app.set('view engine','ejs');
app.set('views', path.resolve(__dirname, 'client', 'views'));
app.get('/', function (req, res){
res.render('index.ejs');
});
app.listen(port, function (){
console.log('SERVER RUNNING... PORT: ' + port);
})`
and in index.js i wrote:
simply HELLO WORLD
but when i opened server.js in Chrome i thought there will be HELLO WORLD but there was server.js code as a text This is what i got
I am learning from Brent Aureli's Tutorials. he is doing all this on windows usng cloudy and i am doing this on Ubuntu!
Please help me It's been 3 days i am stuck in this. Thanks!
You must run server.js via node command like this:
PORT=8080 node server.js
Since you haven't specified port on your server file, you must write it with your node command.
Then, open Chrome and type into address bar localhost:8080 (or other port).
If you don't want to write port every time you run node command, change this line:
var port = process.env.PORT || 8080 // or any other port number

Nodejs on VPS only running on my network

Nodejs server which is installed on my VPS is accessible only on my network. People from outside world cannot access it. If its online, it should either be accessible all over the world or nowhere. What to do?
Code in my js file:
var app = require('express')();
var http = require('http').Server(app);
// Also tried http.listen(3000, "0.0.0.0", function(){
http.listen(3000, function(){
console.log('Server listening to port 3000');
});
Well, in your question you say that you want the Node app to be accessible to everyone in the world, or nobody at all. If you're VPS provider restricts you to only running things on an internal network, however, then it is impossible to do what you are asking.
The network rules will simply not allow it.
With that said, however, I'm going to make a recommendation for changing your Express application. Here's how it should look:
let express = require('express');
let app = express();
app.listen(3000);
The code above will bind your Node application to port 3000 in the simplest way possible using Express directly. This is probably what you want.
Also: please note that if you are intending to build a public service, you will need to likely do one of two things:
Bind your Express server to port 80 (for HTTP), or
Use a web server to proxy requests from port 80 (HTTP) to port 3000 (local).
My bad adding the site's IP as the second parameter of listen function solved it.
http.listen(3000, "xx.xxx.xx.xxx", function(){
console.log('Server listening to port 3000');
});

Categories

Resources