I'm testing out an app (hopefully to run on heroku, but am having issues locally as well). It's giving me an EACCES error when it runs http.Server.listen() - but it only occurs on some ports.
So, locally I'm running:
joe@joebuntu:~$ node
> var h = require('http').createServer();
> h.listen(900);
Error: EACCES, Permission denied
at Server._doListen (net.js:1062:5)
at net.js:1033:14
at Object.lookup (dns.js:132:45)
at Server.listen (net.js:1027:20)
at [object Context]:1:3
at Interface.<anonymous> (repl.js:150:22)
at Interface.emit (events.js:42:17)
at Interface._onLine (readline.js:132:10)
at Interface._line (readline.js:387:8)
at Interface._ttyWrite (readline.js:564:14)
I don't have anything running on port 900 (or any of the other 20 ports I've tried), so this should work. The weird part is that it does work on some ports. For instance, port 3000 works perfectly.
What would cause this?
I figured out that on my local computer, the EACCES error is coming because I have to run node as root in order to bind to those certain ports. I don't know why this happens, but using sudo fixes it. However, this doesn't explain how I would fix it on Heroku. There is no way to run as root on Heroku, so how can I listen on port 80?
As a general rule, processes running without root privileges cannot bind to ports below 1024.
So try a higher port, or run with elevated privileges via sudo
. You can downgrade privileges after you have bound to the low port using process.setgid
and process.setuid
.
It's possible another process is already listening on this port, or the ports have been added to an excluded range.
To show excluded ranges
> netsh interface ipv4 show excludedportrange protocol=tcp
To remedy, either choose another port, or you can try to release the ranges by restarting the winnat
service.
Run cmd
with admin rights.
> net stop winnat
> net start winnat
When running your apps on most platform as a service offerings, you have to use the port as specified in the PORT environment variable.
See http://devcenter.heroku.com/articles/node-js for an example
const server = require('http').createServer();
const port = process.env.PORT || 3000;
server.listen(port, () => console.log(`Listening on ${port}`));