Running Node app via PM2 on port 80
Asked Answered
U

5

19

I have an express that I want to run on port 80. --> app.listen(80);

I'm using PM2 to manage the app (restarting, stopping, monitoring, etc.) . I have a deployment shell script whose last command is PM2 restart index. From the console output, I see no errors and PM2 reports that it successfully completed the command. Yet when I got to my.ec2.ip.address:80 the site is not up. Furthermore, if I run node index.js in my server project directory, I get a Error: listen EACCES 0.0.0.0:80. This makes some sense to me as port 80 is below 1024 and therefore a privileged port. sudo node index.js will allow the launch to work.

I'm a newbie to unix, servers, permissions, and deployment, so in addition to the solution, an explanation of the fundamental concepts contributing to my problem would be greatly appreciated. For instance.. is it bad to simply run my node app as super-user? Is it good practice to run PM2 (therefore possibly running node as..?) root/super-user? The command sudo PM2 restart index leads to sudo: pm2: command not found. Why is PM2 not found when running sudo PM2.. if PM2 is in my path?

Ultimately though, when using PM2 how can I ensure that my server runs on port 80? not found.

Urrutia answered 4/7, 2017 at 17:5 Comment(0)
C
17

Dont use port 80, run on other port like 8080 and redirect 80 to that port with this command

  sudo iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080
Cablegram answered 21/8, 2017 at 7:28 Comment(1)
After running this I was able to access example.org:80, but example.org didn't. To undo this command: lubos.rendek.org/remove-all-iptables-prerouting-nat-rulesTectonic
H
7

It's good to run as little as possible as a priviliged user, as you want to restrict the potential damage in case someone exploits your program. You don't want to run your Node code as root unless you absolutely have to.

Therefore, it's better to run your Node program on an unprivileged port (say, port 8000), and instead have a lightweight web server such as Nginx listen on port 80 and simply forward traffic to your Node program.

If you want to go with Nginx, you can use this configuration to do exactly what I described above, and then just listen with your Node program on port 3000:

server {
  listen 80 default;
  listen [::]:80 default;

  location / {
    proxy_pass http://127.0.0.1:3000;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-for $proxy_add_x_forwarded_for;
  }
}
Holcman answered 4/7, 2017 at 17:22 Comment(0)
R
4

I had the same issue, for the ubuntu server. Fixed with the tutorial below.

sudo apt-get install libcap2-bin
sudo setcap cap_net_bind_service=+ep /usr/local/bin/node

https://www.digitalocean.com/community/tutorials/how-to-use-pm2-to-setup-a-node-js-production-environment-on-an-ubuntu-vps

Also here is another solution from PM2

sudo apt-get install authbind
sudo touch /etc/authbind/byport/80
sudo chown %user% /etc/authbind/byport/80
sudo chmod 755 /etc/authbind/byport/80

https://pm2.keymetrics.io/docs/usage/specifics/#listening-on-port-80-w-o-root

2024 Update

Even though my answer is correct, I highly recommend using @Frxstrem's answer both flexibility & security-wise. Letting Node to use port 80 is not a wise idea.

You can implement additional security layers with stuff like Nginx. Also can run multiple Node.JS servers sharing port 80 with different URLs.

Reinaldo answered 16/11, 2019 at 3:13 Comment(0)
E
3

Though, you may have solved the issue but for the one who comes here facing the same issue, this worked me :

For just troubleshooting, run your app using sudo npm start. If your app runs normally then you need to bind port 80 with the help of authbind package. Run these commands :

sudo apt-get install authbind
sudo touch /etc/authbind/byport/80
sudo chown %user% /etc/authbind/byport/80
sudo chmod 755 /etc/authbind/byport/80

Replace %user% with the user you run pm2. Mine was ubuntu by default.

Set start command in your package.json file to pm2 start <server_file_name>. Run the app using npm start. It should work !

Eb answered 28/12, 2019 at 12:39 Comment(0)
B
2

After lot of time spent configuring nginx, finally uninstall it and followed A.J. suggestion to configure iptables. Thank you A.J.

sudo iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080

But, if anyone know a perfect tutorial to configure nginx, would be a great help.

Bedspring answered 22/11, 2017 at 11:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.