ChatGPT解决这个技术问题 Extra ChatGPT

How do I run Node.js on port 80?

My aim is to run Node.js on port 80. This is because I am finding node.js is being blocked from certain networks which do not allow traffic from any other port.

It appears that the best way to do this is by proxying Apache through Node.js. I have tried using node-http-proxy to do this but I have not had any luck.

The code I am using is here:

var util = require('util'),
    http = require('http'),
    httpProxy = require('http-proxy');

httpProxy.createServer(9000, 'localhost').listen(80);

http.createServer(function (req, res) {
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.write('request successfully proxied to: ' + req.url + '\n' + JSON.stringify(req.headers, true, 2));
  res.end();
}).listen(9000);

But I keep getting the error "Address in use" for port 80. I must be doing something wrong.

How do I proxy Apache through node.js using node-http-proxy? Will this enable me to run node.js on port 80? And is node-http-proxy the best way to achieve this?

Thank you.


f
fullstacklife

run your app on a high port 8080 or whatev then

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

If you are not using ngnix or apache


Also would be helpful to know how to undo this. "--to-port 80" I don't think is the perfect solution. It still has to handle this binding.
And just like that, Nginx has been eliminated.
To UNDO this: sudo iptables -D PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080 (basically change the -A to a -D. That's all)
how to set a specific ip here?
@fullstacklife what if I am using apache too along side?
K
Kyle Chadha

The simplest solution: safely configure your node app to run on port 80.

sudo apt-get install libcap2-bin

sudo setcap cap_net_bind_service=+ep /path/to/node

Ta da! You're done.

Why do I like it?

You don't have to use apache or nginx

You don't have to run your application as root

You won't have to forward ports (and handle that each time your machine boots)

Reference Link: https://www.digitalocean.com/community/tutorials/how-to-use-pm2-to-setup-a-node-js-production-environment-on-an-ubuntu-vps (A great article on how to set up your node app on cloud hosting).


Kudos for not only providing the most elegant solution, but providing a legit reference link.
This is just what I needed. I spent a while scratching my head trying to figure out why I could launch my Express HTTP server in node on every port except 80.
Excellent! One just needs to remember to do this again if he upgrades Node (e.g. with nvm).
This is also useful for other platforms besides node.
It did not work for me. I did sudo setcap cap_net_bind_service=+ep /usr/bin/nodejs (for mac). When I do netstat -tlpn it still shows apache2 on port 80 and nodejs on 8000. What am I doing wrong?
P
PaulM

What you need to do is have 2 ip's for the server you are running. Apache has 1 ip bound to port 80 and then node.js has the other ip bound to port 80.

Using node and its listen directive has 2 values eg. .listen(80, NODEJS_IP or DNS NAME);

Some other advice.

I would not use apache with nodejs as it's not evented. So this really isn't recommended. I would actually look into using NGINX as its a much better pairing with Node.


@PaulM. Thanks. How do I go about binding the secondary IP to port 80 and node.js rather than Apache?
With your dns have something like www.domain.com for 1 ip and chat.domain.com for the other ip. In apache listen to the first ip address: Listen vvv.xxx.yyy.zzz:80. Then with node do .listen(80, chat.domain.com). This is the setup that I am using and I have had no problems with any corporate firewalls, etc.
I wouldn´t recommend nginx for node. Nginx does not support HTTP 1.1 which means you will not be able to do some WebSocket stuff. When you use node.js, I think you will want to use this really fast ;)
@FlashFan, I'm able to do WebSocket stuff with Chrome just fine with my site. Can you elaborate further?
@PaulM - I am having troubles trying to bind Apache to a specific IP. I have Q here: serverfault.com/questions/273143/… Did you have any issues when you did this?
W
Waquo

It is currently not recommended to run node on port 80, as that requires running node as root.

How attached are you to apache? Proxying node through nginx is a tried and true solution, with an nginx-config such as this:

upstream node_cluster {
    ip_hash;   
    server 127.0.0.1:8000;
    server 127.0.0.1:8001;
    server 127.0.0.1:8002;
}

server {
    listen 0.0.0.0:80;
    server_name foo;
    access_log /var/log/nginx/foo.log;

    location / {
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;

      proxy_pass http://node_cluster/;
      proxy_redirect off;
    }
}

Nginx documentation:

http://wiki.nginx.org/HttpProxyModule

http://wiki.nginx.org/HttpUpstreamModule


Plenty of people run node on port 80. Proxying through nginx requires some overhead. Also you don't need root to run on port 80. See here for more info: comments.gmane.org/gmane.comp.lang.javascript.nodejs/8959 I'm not running node via root myself.
Thanks Waquo. I am looking at my options ATM. Nginx may be the way forward.
Look at dryprogrammers answer for how to run Node on port 80 w/o being root.
This answer makes me feel like I can serve both node and php applications from the same server and IP, using different ports for each app, but I'm not so familiar with nginx to be sure it it is actually possible...
n
nicolaskruchten

Your code looks like example code in which you're creating a Node-based proxy from port 80 to port 9000, and then creating a Node-based HTTP server on port 9000. (i.e. Node:80 -> Node:9000)

You are getting "address in use" when you launch Node because Apache is already using port 80. If you want to use Apache to proxy, you must use Node on a different port (say 9000) and have Apache listening on port 80 and forwarding the requests to Node on port 9000. (i.e. Apache:80 -> Node:9000)

It looks like the library you're using is for doing the opposite: using Node as the proxy and forwarding requests to Apache. In this case you must configure Apache to run on another port than port 80. (i.e. Node:80 -> Apache:9000).

Are you wanting to do Node:80 -> Apache:9000 or Apache:9000 -> Node:80, in the end?

EDIT after comments: If you want to do Apache:80 -> Node:9000, you can use mod_proxy on Apache and use the ProxyPass/ProxyPassReverse directives, something like

ProxyPass /nodeurls/ http://localhost:9000/
ProxyPassReverse /nodeurls/ http://localhost:9000/  

where nodeurls is the family of URLs you wish for Apache to forward to Node.


Thank you. I am not too sure. Sorry! I want node to run on apache:80. So.. Node:9000->Apache:80. Not too sure if this is correct.
If you want to run Apache on port 80, then you must run Node on another port, say port 9000. In that case, you must configure Apache to forward some of its requests to Node. I would write this as Apache:80 -> Node:9000 to continue what I've written above.
Ah OK. I see. How do I go about getting Apache to forward some of its requests to Node?
See my edits, you'll have to do install a module and configure it.
I think you meant Apache:80 -> Node:9000 instead of Node:80 -> Node:9000 in the first line.
C
Community

I was having the same issue, here is how I resolved it using node-http-proxy to listen on port 80, then forward to either express or apache.

https://stackoverflow.com/a/9645091/500270


C
Chhaileng

If you are a non-root user, you cannot run or bind with ports lower than 1024 (in Unix system). To allow non-root user can run node on port lower than 1024 use this command.

$ sudo setcap 'cap_net_bind_service=+ep' $(which node)

D
Dennis Kiprotich

I had the same issue, I just changed my port to 8080 and it worked.

httpsServer.listen(8080, () =>
    console.log(chalk.rgb(208, 60, 240)(`Server listening on port: 8080`))
  );

j
jiahut

if you just in develop environment mode

you can su root, then

node index.js or ./node_modules/coffee-script/bin/coffee index.coffee


I'm no network admin but for security's sake I would highly recommend not running a server with root privileges.