listen EADDRINUSE: address already in use -> No matter what port I use? - node.js

NodeJS version: LTS 12.17 installed like this:
curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
sudo apt install nodejs
I have a pretty weird issue:
One of my NodeJS app suddenly reports: listen EADDRINUSE: address already in use and it doesn't help anything no matter what port # I try to change it to?
The full trace-stack looks like this:
Error: listen EADDRINUSE: address already in use 0.0.0.0:6080
at Server.setupListenHandle [as _listen2] (net.js:1313:16)
at listenInCluster (net.js:1361:12)
at doListen (net.js:1498:7)
at processTicksAndRejections (internal/process/task_queues.js:85:21)
I'm listening like this (_wl = a Winston logger instance):
> _server.listen(_port, '0.0.0.0', function () { _wl.info('SERVER STARTED! (listening on port # ' + _port + ')')});
I have just setup this AWS EC2 Ubuntu 20.04 instance - so I guess somehow it has something to do with this. It has been working for years on a lot of different instance earlier Windows (I guess I have never run it on Ubuntu earlier).
I execute like like:
1. cd into folder
2. node ./server.js (I have also tried to use Sudo)
Can it have something to do with permissions?
I have tried to allow all in /out going traffic in the server atteched Security Group.
I have check that the firewall in Ubuntu 20.04 is disabled as well.
Also, on the same server I'm running a Python app which exposes a web socket server and the NodeJS app has no issue to subscribe to this connection...
And yes - I have tried to check all ports in use at the server and only few ports are in use.
The NodeJS app also try to expose a websocket server at a given port - but no matter what port I try to use I get the error above.

Sorry!
I use express in my NodeJS apps and most of my apps contain the following line:
app.listen(port); // In this case port # 6080
Later on in the current app (in which I experience the issue described above) I initialize a web socket server as well like this:
const _server = require('http').createServer();
_server.on('request', app);
_server.listen(_port, '0.0.0.0', function () { _wl.info('WEB SOCKET SERVER STARTED! (listening on port # ' + _port + ')')});
in the code above both port and _port used the same ENV variable/setting(6080). Do to my app/Express in this case actually didn't use the app.listen(port) to anything and that Windows just choose to overrule the port's use-case when the web socket server afterwards got initialized with the same port number --> is the reason why I never have experienced any issues on Windows. But Linux/Ubuntu is more sensitive in this regard.
Cheers! :-)

Related

Node.js: Making Hello World page public

I copied the Hello World example from
https://nodejs.org/en/about/
and it works fine on my Ubuntu cloud instance. Now I'd like to make the Hello World page visible to the entire Internet. What changes are required to the code to accomplish this?
Update: When port is set to 80 and hostname is set to the instance IP address, the following errors are generated when attempting to initiate a node.js session:
ubuntu#instance04:~/NodeJS/NodeHW$ node index01
events.js:183
throw er; // Unhandled 'error' event
^
Error: listen EACCES <my_ip_address>:80
at Object._errnoException (util.js:1022:11)
at _exceptionWithHostPort (util.js:1044:20)
at Server.setupListenHandle [as _listen2] (net.js:1334:19)
at listenInCluster (net.js:1392:12)
at doListen (net.js:1501:7)
at _combinedTickCallback (internal/process/next_tick.js:141:11)
at process._tickCallback (internal/process/next_tick.js:180:9)
at Function.Module.runMain (module.js:686:11)
at startup (bootstrap_node.js:187:16)
at bootstrap_node.js:608:3
You should be able to view the page on your server using its IP. But you may need to take a couple of steps first:
Take note of which port your Node app is listening on. 3000? 80? In production (i.e. on your cloud server instance), it would be customary to run your application on the default HTTP port, which is 80. But other ports are fine to use too.
Depending on your cloud provider, you may have to adjust its Network Settings before it allows any inbound traffic from the internet through to your server. On AWS, for example, each instance is bound to a Security Group. Think of this as a cloud-level firewall that controls internet access to and from your server. On AWS, again as an example, you'd have to adjust your Security Group Inbound Rules to allow TCP connections to be established to port 80 (or whichever port your Node app is listening on). Here's a sample picture of what it looks like. In this example, I've opened port 80 of my server for TCP traffic. Open whichever port that your Node app is listening on. The protocol for HTTP is TCP.
Furthermore, you may have to also adjust your server's internal firewall settings. On Ubuntu, in order to check the status of the firewall, issue this command:
$ sudo ufw status
If the status is inactive, then it means Ubuntu is not enforcing any firewall rules. If it's active, however, you need to make sure that it is allowing incoming traffic to your Node app's port. I'll let you research how to adjust ufw settings.
Finally, obtain the Public facing IP address or assigned domain name of your server. On AWS, this information is available on your instance details view:
So, now you should be able to browse, from anywhere on the internet to your server's public IP and your Node app's port and view the page.
http://ip:port
If your server's IP is 123.123.123.123 and your Node app is listening on port 3000, then the address would be http://123.123.123.123:3000. If your Node app is listening on port 80, then there's no need to specify the port when you browse. So you can simply go to: http://123.123.123.123
I received the answer from tech support at DreamHost.com. I quote: "The problem is that in order to bind to any port lower than 1000, you need to use sudo."
I am using port 80, so the following works:
sudo node index01
Update: The exact limit is 1024, i.e., when a port lower than 1024 is used sudo must precede the node command.

Running node app digitalocean and accessing it

Im running my node app with grunt on a DO droplet. I start the server
Running "connect:server" (connect) task
Waiting forever...
Started connect web server on http://localhost:3000
But when I navigate to my dropletIP:3000 I cannot see the app, I get:
This site can’t be reached
mydropletIP refused to connect.
Shouldn't my app be available? I don't have nginx or anything installed.
I was having similar problem but the solution was simple. Change from 'localhost' to '0.0.0.0' i.e
.listen(8080, '0.0.0.0');
And then to test your api just enter your static ip of droplet with port that you have entered i.e droplet-ip:8080
Check the particular port is opened or not ,using following command
sudo ufw status
If any Firewall enabled and any port is block means you can see that.
netstat -an | grep "LISTEN " ( List of listening port on server)
I need this info ,then only we can find a problem

I currently run my amazon ec2 instance on port 3000. I want to run it on port 80 instead. How can I do it?

I have a node.js app that runs on port 3000. I deployed it on amazon web services (ec2) and it works over there. My server.js file says:
var port = process.env.PORT || 3000;
(...)
app.listen(port);
console.log('App listening on port ' + port);
My security group in aws settings seems to have the port 80 also opened:
so I thought it's enough to just change the var port to = 80 and restart the server. But when I did that I got an error:
bitnami#ip-172-31-47-102:~/apps/myproject/www/myproject$ sudo node server.js
App listening on port 80
events.js:141
throw er; // Unhandled 'error' event
^
Error: listen EADDRINUSE :::80
at Object.exports._errnoException (util.js:856:11)
at exports._exceptionWithHostPort (util.js:879:20)
at Server._listen2 (net.js:1237:14)
at listen (net.js:1273:10)
at Server.listen (net.js:1369:5)
at Function.app.listen (/opt/bitnami/apps/myproject/www/myproject/node_modules/express/lib/application.js:542:24)
at Object.<anonymous> (/opt/bitnami/apps/myproject/www/myproject/server.js:43:5)
at Module._compile (module.js:398:26)
at Object.Module._extensions..js (module.js:405:10)
at Module.load (module.js:344:32)
at Function.Module._load (module.js:301:12)
at Function.Module.runMain (module.js:430:10)
at startup (node.js:141:18)
at node.js:1003:3
I'm using the Bitnami MEAN 3.2.1-0 system on Amazon.
Also, the reason why I want to change this port is this:
so far all my webservices operate on port 3000. However, I also have there a public_html folder with the index.html file. So when any user wants to display my webpage he has to enter not only the webpage, but also the port (3000) which is not that convenient.
So far the whole app stays under www.ec2-some-random-amazom-numbers.eu-west-1.compute.amazonaws.com:3000/index.html so I will buy a normal top level domain to point at it (eg. something.com ) but then - do I still need to change the port 3000 to 80 in that case? Or maybe it's common to leave apps on port other than 80?
If the latter, then will it be possible for me to leave the port as it is and just point the top level domain on this whole long amazon one with a port 3000 at the end?
So for example: when user types www.something.com it will redirect him to
www.ec2-some-random-amazom-numbers.eu-west-1.compute.amazonaws.com:3000/index.html ?
Something like this should work for you:
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 3000
You want to use iptables to forward request coming in on port 80 to port 3000 internally.
Based on the error you're getting, (EADDRINUSE), some other web server is listening on port 80 already on your server. If you can prevent that server from running, then you can change your app to run on port 80.
Do the following:
Figure out what's already running on port 80 on your server. There's a good chance it's Apache. Try using netstat to verify.
Kill it (and prevent it from restarting). This will depend on whats listening.
Move your app to port 80 just like you've already tried.
Additional resources:
http://www.cyberciti.biz/faq/what-process-has-open-linux-port/
If you are using the Bitnami Mean Stack then Apache is listening in port 80, hence the conflict. You can either stop the bundled Apache:
sudo /opt/bitnami/ctlscript.sh stop apache
Or you could add a ProxyPass rule in the Apache configuration:
https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypass
I use nginx proxy server for port forwarding
I have faced the same issue.
The solution is to start your NodeJs or ExpressJs app using Port 80, I mean
var port = 80 and start the app using sudo node bin/www
My issue is not able to access the app from internet when the app is running on port 3000: NodeJs App in AWS using port 3000 is not accessible from Internet

socket.io redis store on openshift

I'm trying to set up socket.io on node.js to use redisstore so i can comunicate with pubsub with multiple node on the opeshift platform, but i can't manage to connect to the redis server. I'm using this cartridge.
I tried to connect with
var pub = redis.createClient(process.env.OPENSHIFT_REDIS_DB_PORT,
process.env.OPENSHIFT_REDIS_DB_HOST);
but it doesn't work (and I found out why: createClient() only accept IP addresses) and it fallback to the default port and host, then I ran rhc port-forward:
$ rhc port-forward appname
Checking available ports ... done
Forwarding ports ...
Address already in use - bind(2) while forwarding port 8080. Trying local port 8081
To connect to a service running on OpenShift, use the Local address
Service Local OpenShift
--------------- --------------- ---- ----------------------------------------------
haproxy 127.0.0.1:8080 => 127.5.149.130:8080
haproxy 127.0.0.1:8081 => 127.5.149.131:8080
s_redis_db_host 127.0.0.1:54151 => blabla.appname.rhcloud.com:54151
Press CTRL-C to terminate port forwarding
So I tought I was doing all wrong and I had to set just the port like this:
var pub = redis.createClient(process.env.OPENSHIFT_REDIS_DB_PORT);
but all I get is this
info: socket.io started
events.js:72
throw er; // Unhandled 'error' event
^
Error: Redis connection to 127.0.0.1:54151 failed - connect ECONNREFUSED
at RedisClient.on_error (/var/lib/openshift/532c3790e0b8cd9bb000006b/app-root/runtime/repo/node_modules/socket.io/node_modules/redis/index.js:149:24)
at Socket.<anonymous> (/var/lib/openshift/532c3790e0b8cd9bb000006b/app-root/runtime/repo/node_modules/socket.io/node_modules/redis/index.js:83:14)
at Socket.EventEmitter.emit (events.js:95:17)
at net.js:426:14
at process._tickCallback (node.js:415:13)
DEBUG: Program node server.js exited with code 8
I tried to connect via
telnet $OPENSHIFT_REDIS_DB_HOST $OPENSHIFT_REDIS_DB_PORT
And it works fine... Do you have any suggestions? Am I doing it wrong? (I'm still new to redis and socket.io)
(I omitted the rest of the code 'cause I know it works, I have no problem on my local machine, I just can't get the connection...)
Thanks a lot
but it doesn't work (and I found out why: createClient() only accept IP addresses) and it fallback to the default port and host
It does support Host, createClient uses net.createConnection(port, host); that does support hostname.
The following code will help you find the issue:
console.log(process.env);
var pub = redis.createClient(process.env.OPENSHIFT_REDIS_DB_PORT,
process.env.OPENSHIFT_REDIS_DB_HOST, {auth_pass: process.env.OPENSHIFT_REDIS_DB_PASSWORD});
pub.on('error', console.log.bind(console));
pub.on('ready', console.log.bind(console, 'redis ready'));
Does your openshift Redis instance requires AUTH ?
don't know if it is about a recent change on openshift, but i think the problem is in the variables. Although they work for telnet.
you can try this
var redisHost = process.env.OPENSHIFT_REDIS_HOST;
var redisPort = process.env.OPENSHIFT_REDIS_PORT;
var redisPass = process.env.REDIS_PASSWORD;
var client = redis.createClient( redisPort, redisHost );
client.auth( redisPass );

Node.js and Apache: connection issues

I have installed Node.js with Socket.io on a CentOS server which is running Apache on port 80.
I created a socket test, which justs listens on port 8080.
If I curl the address localhost:8080 from within the server's shell, I get the Socket.io-welcome message. If I have a line like this:
<script src="http://localhost:8080/socket.io/socket.io.js"></script>
Then the browser cannot find the file.
A "solution" was to proxy requests to /nodejs/ to http://localhost:8080/, but this solution did not work for very long.
Is it possible to run the Node.js server when we have Apache installed? Which settings must be changed in order for us to access the url: http://server.com:8080 ? It seems the Node.js only accepts connections from localhost.
Problem is most probably in your node.js program.
It should listen on 0.0.0.0 and not 127.0.0.1 which is local only.
So where you've got something like:
.listen(8080, '127.0.0.1'); // '127.0.0.1' or 'localhost'
You should change it to:
.listen(8080); // or 0.0.0.0
Apache will only interfere if it also uses port 8080 but you should get an error when starting your node app if this is the case.
Also, if you connect to http://localhost in your browser, it will only work if the server is on the same local machine as the browser. Fine for testing I guess.
You'll have to connect to a domain or ip address if you have a hosted server else no browser will find it.
Update:
Your socket.io code also needs to connect correctly:
var socket = io.connect('http://correct.server.com:8080'); // not localhost
and your browser needs to load the javascript file from the correct place:
<script src="http://correct.server.com/socket.io/socket.io.js"></script> // not localhost
This might help with firewall / load balancer issues:
https://github.com/LearnBoost/socket.io/wiki/Socket.IO-and-firewall-software

Resources