Node.js connect only works on localhost
Asked Answered
A

12

55

I have written a small Node.js app, using connect, that serves up a web page, then sends it regular updates. It also accepts and logs user observations to a disk file.

It works fine as long as I am on localhost, but I can't get other computers on the same intranet to see it. I am using port 3000, but changing to port 8080 or 80 didn't help.

Here is the code I am using to set up the connection:

var io = require('socket.io'),
  connect = require('connect');

var app = connect().use(connect.static('public')).listen(3000);
var chat_room = io.listen(app);

As stated above, I've tried changing the port number to 8080 or to 80 and didn't see any difference, so I don't think that it is a firewall problem but I could be wrong.
I've also thought about, after reading similar questions dealing with HTTP, to add 0.0.0.0 to the listen() method but it doesn't seem that listen() takes an IP mask parameter.

An answered 26/12, 2012 at 17:25 Comment(5)
sometimes your ISP will block ports 80 and 8080. I am inclined to say that the problem is your router, firewall or isp.Trixy
Connect's listen() essentially wraps Node's http.Server#listen, which by default accepts connections from all IP addresses (host 0.0.0.0), so that's should be the problem.Reputable
mkoryk, I am on a LAN, my attempts have all been within the LAN. It is my router, and as far as I can see, the ports are not blocked.An
Miikka, I'm not sure, but I think that you are telling me that what I have should work.An
To those who came here via Google: If you've hosted service on Google cloud and facing this issue, first make sure you've added the port in the exception rules of cloud firewall as well as in the operating systems firewallBroadminded
R
117

Most probably your server socket is bound to the loopback IP address 127.0.0.1 instead of the "all IP addresses" symbolic IP 0.0.0.0 (note this is NOT a netmask). To confirm this, run sudo netstat -ntlp (If you are on linux) or netstat -an -f inet -p tcp | grep LISTEN (OSX) and check which IP your process is bound to (look for the line with ":3000"). If you see "127.0.0.1", that's the problem. Fix it by passing "0.0.0.0" to the listen call:

var app = connect().use(connect.static('public')).listen(3000, "0.0.0.0");
Rheumy answered 26/12, 2012 at 19:21 Comment(5)
Thanks Peter. I tried the "0.0.0.0" but forgot the quotation marks around it. Yes, netstat showed that the socket server was bound to 127.0.0.1. I can, now, from the same machine contact the node.js server from either localhost or from the IP address assigned by dhcp. I'm still not getting to the server from other machines on the same network. I'll go back to checking all of the firewalls and the routers. It shouldn't be as difficult as I am making it, since they are all under my control.An
OK, great. If the machines are truly on the same network (same local subnet), then traffic will flow directly host to host without transiting the router. So most likely it's a firewall on one of the hosts themselves.Rheumy
I'm seeing the following. Does this mean the 'all' port is bound? tcp6 0 0 :::5000 :::* LISTEN 11363/nodeLuetic
Yes it does for tcpv6Rheumy
what does tcp46 0 0 *.3000 *.* LISTEN mean ?Gleaning
T
76

To gain access for other users to your local machine, i usually use ngrok. Ngrok exposes your localhost to the web, and has an NPM wrapper that is simple to install and start:

$ npm install ngrok -g
$ ngrok http 3000

See this example usage:

enter image description here

In the above example, the locally running instance of sails at: localhost:3000 is now available on the Internet served at: http://69f8f0ee.ngrok.io or https://69f8f0ee.ngrok.io

Tandem answered 7/1, 2016 at 15:56 Comment(7)
This is a lot better than what I was originally looking forCaparison
Please note that this solution is not reliable as the forwarding link changed everytime you stop the ngrok service.Veiled
It depends what you are trying to achieve. Commenting that it is "not reliable" without offering the context is unhelpful & misleading. Frequently use ngrok as a developer in order to test services I am developing that are invoked by an external system as part of a web based flow. It has always been reliable and meets those requirements well.Tandem
Wow this is so cool! It exposes my node app in the internet, not just in the local network.Loggia
duuuuuuuuuuuuuuude, This is AWESOME! Lifechanger! LOLTheron
@Tandem i am getting errror - SocketException: OS Error: Connection timed out, errno = 110, address = 10.xxx.xx.xxx, port = 41xxx. in my flutter app from local address api only on real devies but on emulator its working fine any solution.Billings
I want to upvote more than once for this.Gesticulate
E
8

Binding to 0.0.0.0 is half the battle. There is an ip firewall (different from the one in system preferences) that blocks TCP ports. Hence port must be unblocked there as well by doing:

sudo ipfw add <PORT NUMBER> allow tcp from any to any
Empoison answered 4/6, 2013 at 15:36 Comment(5)
sudo ipfw add allow tcp from any to any 3000Aborning
Ashish, rob, I followed your instructions but without luck. Here is my original question https://mcmap.net/q/1633257/-cannot-browse-site-hosted-on-local-machine-from-a-mobile. Could you leave any comment?Rhenium
is ipfw a special brand of unix? doesn't work on Ubuntu 14Luetic
@Luetic try ufw for ubuntuInsole
changed localhost to 0.0.0.0 and it worked ! thanks.Pampero
M
7

On your app, makes it reachable from any device in the network:

app.listen(3000, "0.0.0.0");

For NodeJS in Azure, GCP & AWS

For Azure vm deployed in resource manager, check your virtual network security group and open ports or port ranges to make it reachable, otherwise in your cloud endpoints if vm is deployed in old version of azure.

Just look for equivalent of it for GCP and AWS

Maurizio answered 7/7, 2017 at 4:44 Comment(0)
F
6

I have a very simple solution for this problem: process.argv gives you a list of arguments passed to node app. So if you run:

node server.js 0.0.0.0

You'll get:

process.argv[0] //=> "node"
process.argv[1] //=> "server.js"
process.argv[2] //=> "0.0.0.0"

So you can use process.argv[2] to specify that as the IP address you want to listen to:

http.listen(3000, process.argv[2]);

Now, your app is listening to "all" IP addresses, for example http://192.168.1.4:3000/your_app.

I hope this will help someone!

Firedog answered 29/4, 2017 at 11:14 Comment(0)
S
1

Fedora or Centos distro check your selinux and firewalld in my case firewalld prevented the connection:

Selinux: $sestatus
SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             targeted
Current mode:                   {{checkmode}}
Mode from config file:          {{checkconfig}}
Policy MLS status:              enabled
Policy deny_unknown status:     allowed
Max kernel policy version:      30

Firewalld status: $systemctl status firewalld
Sternmost answered 12/9, 2016 at 22:51 Comment(1)
Turning off my firewalld service did the trick. I can now access my node app from within the local network. But I think that's not the solution. How can I tell my firewall to just allow connecting to my node.js app's port?Loggia
K
1

After struggling with this issue for quite some time I managed to solve it by allowing incoming connections on port 8080.

Since you wrote that the .listen(8080, "0.0.0.0") solution didn't work for you, make sure the connections on port 8080 are allowed through your firewall.

This post helped me to create a new Inbound rule in windows firewall settings.

Katykatya answered 26/10, 2018 at 16:2 Comment(0)
C
1

in my case I had to use both symbolic IP address "0.0.0.0" and call back while listen to server "cors": "^2.8.5", "express": "^4.17.1",

const cors = require("cors");
app.use(cors());

const port = process.env.PORT || 8000;
app.listen(port,"0.0.0.0" ,() => {
  console.log(`Server is running on port ${port}`);
});

you can also use, your local IP address instead of "0.0.0.0", In OS Ubuntu you can find your Ip address by using command

ifconfig | grep "inet " | grep -v 127.0.0.1

enter image description here Then use the Ip Address:

app.listen(port,"192.168.0.131" ,() => {
  console.log(`Server is running on port ${port}`);
});

If you use fixed Ip address such as "192.168.0.131", then you must use it while calling to the server, such as, My api calling configuration for react client is bellow:

REACT_APP_API_URL = http://192.168.0.131:8001/api
Corticosterone answered 14/11, 2020 at 0:27 Comment(0)
T
0

Working for me with this line (simply add --listen when running) :

node server.js -p 3000 -a : --listen 192.168.1.100

Hope it helps...

Toxicogenic answered 24/5, 2017 at 8:33 Comment(0)
S
0

Same problem here, for me solution was in editing server.js file line 161

 var server = app.listen(argv.port, '**<server.ip.adress.here>**', function() {
 console.log('Cesium development server running publicly.  Connect to localhost:%d/', server.address().port);
    });

replace localhost> with <server.ip.adress.here>

Shoshone answered 14/7, 2020 at 13:13 Comment(0)
I
0

CHECK YOUR ANTI-VIRUS FIREWALL SETTINGS.

I have a NodeJS server working on Windows 10 PC, but when I put the IP address and port (example http://102.168.1.123:5000) into another computer's browser on my local network nothing happened, although it worked OK on the host computer.

(To find your windows IP address run CMD, then IPCONFIG)

Bar Horing Amir's answer points to the Windows firewall settings. On My PC the Windows Firewall was turned off - as McAfee anti-virus has added its own Firewall.

My system started to work on other computers after I added port 5000 to 'Ports and Systems Services' under the McAfee Firewall settings on the computer with NodeJS on it. Other anti-virus software will have similar settings.

I would seriously suggest trying this solution first with Windows.

Incomputable answered 1/1, 2021 at 17:32 Comment(0)
S
0

I tried a number of solutions on this thread and none of them worked for me. In case someone has the same problem I had, here is how I fixed my issue.

In my react app, I changed the localhost to the nodejs server IP.

// Interface to server using Axios
const api = axios.create({ 
  baseURL: 'http://server_ip_addr:4000' 
});
Slangy answered 3/11, 2021 at 10:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.