How do I run Node.js on port 80? - apache

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.

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

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).

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.

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

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.

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)

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

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`))
);

if you just in develop environment mode
you can su root, then
node index.js or ./node_modules/coffee-script/bin/coffee index.coffee

Related

how to redirect apache port 80 to jetty port 8080?

I have a VPS server with a domain example.com, with apache2 listening port 80
Then, I have a web app in jetty server (running with mvn jetty:run), listening in port 8080
When I type example.com in a browser, I get a apache example page "it works!"
If I write example.com:8080 I get my webapp
Question is simple, how can I redirect for when I write example.com so that I get to my webapp?
I cant change port jetty to 80, its error.
command "sudo iptables -t nat -I PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080" does not anything effect
So, how can i make apache redirect 80 to 8080? in sites-enabled/default-000?
Please explain carefully, I'm a newbie with systems ;(
Thank you
EDIT
I solved it with this:
http://czetsuya-tech.blogspot.com.es/2012/07/how-to-port-forward-apaches-80-to.html#.VImt1XvyOPU
But last line:
RewriteRule ^/(.*) ......:8080/0,81 € [P,L]
Makes error at restart apache
I deleted it and works fine. Any problem with this? What is RewriteRule?
Using IPTABLES is one possible solution. I don't know much about IPTABLES - but there are a lot of tutorials out there, like this one: http://proghowto.com/iptables-redirect-port-80-to-port-8080
I don't know if that works if you have a running daemon (apache) on the destination port.
The other solution is to use a proxy module in apache to pass requests through to your webapp. On Linux only root users are allowed to use ports below 1000. On Windows you should be able to simply change the port in the jetty configuration.
There are two tutorials I often use, they apply to apache and tomcat but that makes no difference for the apache side:
https://confluence.atlassian.com/display/DOC/Using+Apache+with+virtual+hosts+and+mod_proxy
https://confluence.atlassian.com/display/STASH/Integrating+Stash+with+Apache+HTTP+Server
This is quite a common setup. Also there is almost no performance impact due to the proxying. Not that a user would notice anything.

How to configure nginx to make ssh server via subdomain.domain.tld:80 available

I want to make the ssh server on port 22 available through a subdomain on port 80.
I thought it should by something like this:
server {
listen ssh.domain.tld:80;
server_name ssh.domain.tld;
location / {
proxy_pass http://localhost:22;
}
}
But it won't work. nginx will accept this and start with this configuration, but I only get empty responses from ssh.domain.tld:80.
What am I missing?
Since Nginx Version 1.9.0,NGINX support ngx_stream_core_module module, it should be enabled with the --with-stream. When stream module is enable they are possible to ssh protocol tcp proxy
stream {
upstream ssh {
server localhost:22;
}
server {
listen 80;
proxy_pass ssh;
} }
https://www.nginx.com/resources/admin-guide/tcp-load-balancing/
You should use sslh.
Configure nginx to run on a different port than 80, say 800, and then configure sslh to redirect web traffic to that port in /etc/default/sslh.conf file.
This setup may take 15 min. or less.
basically you're looking in the wrong place:
stock nginx can proxy web and/or email traffic, it doesn't handle ssh traffic at all
the subdomain is a dns isue: configure it in your dns settings, you need an A and/or AAAA record linking ssh.domain.tld to your ssh server's ip-adres
the port your ssh server listens on is a ssh server setting (see man sshd_config specifically the ListenAddress and Port directives)

how to put nodejs and apache in the same port 80

I have to put nodejs in port 80, but apache is already using it. How can I put both (nodejs and apache) on the same port 80? I need it because in my university all the ports are blocked except for PORT 80. (This is a realtime application with nodejs and socket.io (websockets) and in the other side a php application).
Thanks a lot
I do this via node.js proxy..
Install http-proxy with npm or official page
Example:
var http = require('http'),
httpProxy = require('http-proxy'),
proxyServer = httpProxy.createServer ({
hostnameOnly: true,
router: {
'domain.com': '127.0.0.1:81',
'domain.co.uk': '127.0.0.1:82',
'127.0.0.1': '127.0.0.1:83'
}
});
proxyServer.listen(80);
This creates a node process listening to port 80, and forwarding requests for domains which go to :81,82,83 etc. I recommend running this with forever and adding an entry to init.d so your proxy is up in case system shuts down.
You can also use Apache 2's mod_proxy and mod_proxy_http, which might be more reliable or perform better depending on your system.
Here's an example:
Firstly run below command to proxy to allow
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod proxy_balancer
sudo a2enmod proxy_balancer
sudo a2enmod lbmethod_byrequests
# Use Apache for requests to http://example.com/
# but use Node.js for requests to http://example.com/node/
<VirtualHost *:80>
ServerName example.com
DocumentRoot /var/www/example/
<Location /node>
ProxyPass http://127.0.0.1:8124/
ProxyPassReverse http://127.0.0.1:8124/
</Location>
</VirtualHost>
And of course you can modify the directives to your needs, such as using a different port for your virtual host (e.g., 443), different port for Node.js, or set up the proxy under a different block, such as for a subdomain (e.g., node.example.com).
I've personally done this the other way round from #liammclennan. Some suggest that proxying through Apache defeats some of the performance and scalability advantages of Node (don't have experience myself as my server doesn't get that much traffic, but from #liammclennan's link: "Every request that comes in through Apache will cause an Apache thread to wait/block until the response is returned from your Node.js process.", which obviously doesn't mesh well with Node's architecture.)
I used node-http-proxy to set up a Node proxy server roughly as described in the first link (my Node proxy runs on port 80; Apache and my other Node services don't). Seems to be working well so far, though I have had occasional stability problems that I've 'solved' through checking the proxy's still running with a cron job (edit: it seems a lot more stable these days). The proxy's pretty lightweight, taking up about 30MB memory.
You can't. You have to run node.js on another port and then proxy requests through apache. You can do this using mod_proxy
http://davybrion.com/blog/2012/01/hosting-a-node-js-site-through-apache/
I usually use haproxy as the front-end in situations like that and have that proxy to the appropriate backend server. (Though making your node.js process a proxy server is a valid approach too depending on your needs).
for httpd.conf
activiate the module , proxy_module and proxy_http
if you are using virtual host
<virtualhost ...>
ServerName api.domain.com
........
ProxyPreserveHost On
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
</virtualhost>
assume you are running nodejs server at 8080 , you don't need to take care ssl in nodejs , all should be done in apache
then try https://api.domain.com/
I found a cool gist Run apache and nodejs on port 80. did not try it yet but will do of course
Step 1
Get a VPS that offers 2 or more IP addresses.
Step 2
From the WHM cPanel, find the menu item Service Configuration,
select Apache Configuration and then click on Reserved IPs Editor.
Step 3
Tick the IP address you DON'T WANT Apache to listen to, and write
it down so you can use it in the next step. Click Save.
Step 4
Install Node.js, and create a server like this:
var http = require('http');
var server = http.createServer(function(req, res) {
res.writeHead(200);
res.end('Hello, world!');
});
server.listen(80, '111.111.111.111');
Replacing 111.111.111.111 with the IP address you previously
reserved from the WHM cPanel.
Step 5
Stop wasting your time and never listen to those telling you to use
mod_rewrite to proxy Node.js again.
Update:
We can solve a problem in many different ways and IMHO, we should at least know each possible way 😉. We can do it without buying a new IP of course putting a proxy in front of both Apache and NodeJS server each running other ports except 80.

Will running node.js with Apache causes too much performance degradation?

I am trying to run Apache and node.js on the same Amazon EC2 instance. After research online, I came up with the following solution:
run Apache on port 9000
run node.js apps on port 8001, 8002 and so on.
create a reverse proxy in node.js, running on port 80. It routes requests to different ports based on the hostname.
This solution works. (Although I haven't found a way to start node.js automatically)
My question is, will running multiple node instance causes performance degradation? Or will the reverse proxy be a problem?
Thanks,
Performance Degradation
On the contrary. If all you do with node is proxying, the overload is insignificant (as compared to apache's). I do have a quite similar setup as yours (small virtual machine, 3 legacy apache websites, node.js proxying and enhancement). So far, apache is the resource eater, not my node apps, which nonetheless proxy/filter/intercept every incoming http request
Here's my setup :
main proxy
which handles all incoming requests (for as many domains as you like) : I personally use nodejitsu's http-proxy which is very robust and simple to configure
var http = require('http');
var httpProxy = require('http-proxy');
var options = {
hostnameOnly: true,
router: {
'domain1.com': '127.0.0.1:8081',
'www.domain1.com': '127.0.0.1:8081',
'subdomain1.domain1.com': '127.0.0.1:8082',
(...)
'domain2.com': '127.0.0.1:8090',
(...)
}
}
var mainProxy = httpProxy.createServer(options);
mainProxy.listen(8080);
You can redirect to apache directly from the option object, or do some more url parsing in another (middleware) node app on a different port.
WARN: if you don't wish to install/run node as 'root' (which I'd strongly advise in a production environement) : redirect port 80 to some other port with an IPTABLE directive (let's say 8080) where this proxy runs (see here for detailed example of Iptable directives). Mine, on a debian squeeze, reads :
#REDIRECT port 80 to 8080
$IPTABLES -t nat -I PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
node apps
which do some URL parsing with regexes, or whatever you need. Ex: redirect to a few (legacy) apache servers which (in my case) only serve legacy content not yet served by the 'in developement' node apps.
Daemonisation
There are several solutions to make node run as a daemon. My favorite two are :
nodemon will monitor all files in your node app folder and subfolder for change and restart the node app on file change. It's perfect for a development environment
forever (yet again by Nodejitsu) will restart your node app if ever it stops. It's very customisable.
Also :
init.d script : I've written this debian init.d script for my own servers (should work on ubuntu)
Node is really really fast and it's build for handling thousands of connections in the same time, so using a proxy built with it won't be a problem at all in my opinion.

https(apache + ssl) is only available from locahost, how to configure to visit it by domain name?

apache + ssl is configured using xampp on windows server 2003. http content has no problem by domain name, but https content can only be visited from localhost. "netstat -a" shows
Proto Local Address Remote Address State
...
TCP hostname:https hostname:0 Listening
...
How to config to enable https via domain name?
Found the reason. Another program take the 443 port so apache https failed. use "netstat -a -o -n" can get the detail.
I'm assuming you can already access apache using this domain name.
Take a look in your ports.conf, usually found at
/etc/apache2/ports.conf
It should contain a line like:
NameVirtualHost *:443
and also
Listen 8443 https