39

I am trying to run a web project by NodeJS on my MacOS.

After npm install, npm start returns an error

events.js:183
  throw er; // Unhandled 'error' event
  ^

Error: listen EACCES 0.0.0.0:443
    at Object._errnoException (util.js:1024:11)
    at _exceptionWithHostPort (util.js:1046:20)
    at Server.setupListenHandle [as _listen2] (net.js:1334:19)
    at listenInCluster (net.js:1392:12)
    at Server.listen (net.js:1476:7)
    at Object.<anonymous> (/Users/softtimur/Startup/PRODSERVER/tmp/WeCard/models/www:36:8)
    at Module._compile (module.js:635:30)
    at Object.Module._extensions..js (module.js:646:10)
    at Module.load (module.js:554:32)
    at tryModuleLoad (module.js:497:12)
    at Function.Module._load (module.js:489:3)
    at Function.Module.runMain (module.js:676:10)
    at startup (bootstrap_node.js:187:16)
    at bootstrap_node.js:608:3

No other website is running on my Mac.

Does anyone know what's wrong? Do I need to configure something on my Mac?

Edit 1:

sudo npm start returns

events.js:183
      throw er; // Unhandled 'error' event
      ^

Error: listen EADDRINUSE :::443
    at Object._errnoException (util.js:1024:11)
    at _exceptionWithHostPort (util.js:1046:20)
    at Server.setupListenHandle [as _listen2] (net.js:1351:14)
    at listenInCluster (net.js:1392:12)
    at Server.listen (net.js:1476:7)
    at Object.<anonymous> (/Users/softtimur/Startup/PRODSERVER/tmp/WeCard/models/www:36:8)
    at Module._compile (module.js:635:30)
    at Object.Module._extensions..js (module.js:646:10)
    at Module.load (module.js:554:32)
    at tryModuleLoad (module.js:497:12)
    at Function.Module._load (module.js:489:3)
    at Function.Module.runMain (module.js:676:10)
    at startup (bootstrap_node.js:187:16)
    at bootstrap_node.js:608:3
SoftTimur
  • 5,630
  • 38
  • 140
  • 292
  • 1
    Ports < 1024 are privileged. See these: https://apple.stackexchange.com/questions/37418/how-can-i-open-port-80-so-a-non-root-process-can-bind-to-it and https://stackoverflow.com/questions/7612053/binding-on-privileged-ports-ports-1024-on-mac-os-x-10-6 – FBergo May 01 '18 at 06:27

5 Answers5

66

In UNIX-like systems, non-root users are unable to bind to ports lower than 1024.

This is a nuisance when proxying addresses on port 80. Typically, you end up sudoing all apps that must bind to such ports.

However, since kernel 2.6.24, you can use the setcap command to set specific capabilities to a program.

To enable all node programs to bind on any port lower than 1024, issue the following command:

sudo setcap 'cap_net_bind_service=+ep' /usr/local/bin/node

Note: If you don't know the location of node, follow below command.

sudo setcap 'cap_net_bind_service=+ep' `which node`
Arjun Kava
  • 5,303
  • 3
  • 20
  • 20
28

In order to listen on privileged ports you need root permissions to start the server; this applies to ports < 1024. You may use nginx as a reverse proxy server running on 443 and run your Node JS server alongside on non-privileged ports as an unprivileged user.

For more information on setting up Node JS application with nginx in production, follow the link: https://www.digitalocean.com/community/tutorials/how-to-set-up-a-node-js-application-for-production-on-centos-7

bschlueter
  • 3,817
  • 1
  • 30
  • 48
Abhishek Singh
  • 2,642
  • 15
  • 24
  • Please see my update. But I have on other app running on 443. – SoftTimur May 01 '18 at 07:08
  • Then you have to choose another port whatsoever. Or if the application is a static webpage or a website, then you can switch to nginx and create multiple vhost configurations for both the applications to run on 443 but with different domain names. Note: Nginx because this can only be used as a reverse proxy server. – Abhishek Singh May 01 '18 at 07:22
7

I think you're probably looking to provide HTTPS to your application, if that's the case then usually with nodejs we don't serve using HTTPS directly from our node application. Instead we use nginx (a web server) to act as a "reverse proxy". This means nginx sits in front of our application, it listens on port 443 for us, and then sends requests through to our desired application.

Using nginx you can listen on port 443 and then redirect to multiple different services depending on the hostnames etc. For instance, I might have 3 web services running on one server, with nginx I can listen on port 443 for any HTTP connection. If the HTTP request is going to the host myblog.com it can send it off to a node service listening on port 8081. If the hostname on the request is myresume.com it might go off to a serivce on port 8082 and myprivatethings.com could go to port 8083.

Using something like nginx (many alternatives exist) you can manage multiple services with SSL/TLS (https) on one server.

Elliot Blackburn
  • 3,759
  • 1
  • 23
  • 42
5

Foremost, do not run as root. That's asking for 'it'. Don't run your node web project as root.

Instead, use PM2 and authbind to do this:

// %user% is whatever user is running your code
sudo touch /etc/authbind/byport/443
sudo chown %user% /etc/authbind/byport/443
sudo chmod 755 /etc/authbind/byport/443

Next, add this alias to your ~/.bashrc or ~/.bash_profile:

alias pm2='authbind --deep pm2'

Then, try it with pm2:

pm2 start app.js
4Z4T4R
  • 2,340
  • 2
  • 26
  • 45
  • Note that %user% is a placeholder for the user that all owns all application files. – 4Z4T4R Jul 10 '19 at 07:20
  • Yes, I replaced it with the correct user name. I still get EACCESS errors. – Jim Jul 11 '19 at 14:24
  • @Jim - More info on PM2 and authbind is here: http://pm2.keymetrics.io/docs/usage/specifics/ I'm not understanding the spammy downvotes to this as this is standard practice in production for many nodejs projects. – 4Z4T4R Jul 29 '19 at 21:07
  • 2
    If the alias doesn't work for you you can use interpreter and interpreter args instead: pm2 start app.js --interpreter="authbind" --interpreter-args="node" (you can also include that in the ecosystem.config.js file to save you the need to add this in the cli) – Ezra Steinmetz Oct 18 '21 at 20:13
0

On SLED (SUSE)

On file /etc/sysctl.conf

Add the line net.ipv4.ip_unprivileged_port_start=400

Restart system after that

Welyngton Dal Prá
  • 758
  • 1
  • 10
  • 19