Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
How to run Apache and Node.js together (the right way)

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.

@internetlab

This comment has been minimized.

Copy link

commented Oct 10, 2011

Good idea..

@grisevg

This comment has been minimized.

Copy link

commented Dec 1, 2011

what if you don't have 2 ip addresses?

@stagas

This comment has been minimized.

Copy link
Owner Author

commented Dec 1, 2011

You'd need to use something like haproxy behind apache and node to route traffic to either, or run node on a different port than 80.

@skw

This comment has been minimized.

Copy link

commented Apr 3, 2013

cPanel :(, it's pretty easy to setup nginx to reverse proxy to a node.js server , then you can use something like forever, upstart and/or monit to manage your node.js processes.

@morales2k

This comment has been minimized.

Copy link

commented May 30, 2013

This was really easy!! Thanks for the simple how-to!!!

Now all I need is a script to auto-run the nodejs server in my CentOS 6.3 machine... otherwise I will need to SSH connect to the server and do #node server.js# every time ... and if the server restarts without me knowing (its a managed reseller server) well... whatever we do with node will suffer without that script...

Anyways, this was a great help. Kudos for sharing this!

@davidnknight

This comment has been minimized.

Copy link

commented Jun 10, 2013

Thanks for the tutorial, will be trying this myself. =)

@jlmorales You can install Forever via npm to keep your nodejs server running. Here's a tutorial: http://blog.nodejitsu.com/keep-a-nodejs-server-up-with-forever

@shane-reaume

This comment has been minimized.

Copy link

commented Dec 16, 2013

I did get it to work but then it broke my other websites as the IP's are shared, even though the removed IP is only a backup to the domains. It actually broke cPanel, email and root domain access on four websites until I set it back.

I am currently ordering 2 more IP's and will test on one of those.

@vertebrac

This comment has been minimized.

Copy link

commented Dec 23, 2013

I followed the steps carefully but when i try to start the test code i still get the Error: listen EADDRINUSE
Can both process (apache and nodejs) can work in the same port (80) even if they are in different ip?
Thanks!!

@vertebrac

This comment has been minimized.

Copy link

commented Dec 23, 2013

@vertebrac, in whm 11.40, when you try to save the "reserved ip" change, it shows an error: "Address family for hostname not supported: alloc_listener: failed to set up sockaddr for ::" the quick fix is running the Easy apache tool, and then the error is gone and everything works good. Thanks for the post! excelent solution!

@tcrebbs

This comment has been minimized.

Copy link

commented Jan 5, 2014

This is a terrible idea. How come anyone who ever says "The right way" invariable proceeds to tell you the wrong way to do something.? Is it perhaps because the type of person who thinks there is only one right way is ipso facto wrong?

Anyway you now have a service (a node server) running as ROOT (since port 80 is privileged and you have done nothing to separate out the privileges) (unless you are running this on a windows server in which case you are already wrong.) You are also wasting an IP for no good reason, though that is a trivial point. Put it behind nginx if you must, or apache, or haproxy for all I care. Don't run your server with root permissions. Jeesh.

Also, if you are making anything you are ever going to use, one day you will be happy to have a real server with abilities like mod_rewrite at your disposal.

@rsenn

This comment has been minimized.

Copy link

commented Mar 30, 2014

i think there are countless situations (generally said) potentially involving node.js and apache. I think the use case of the poster is not defined, respectively put in a specific context. Basically his frame is "Running a node.js HTTP server which listens on the default port when there's already an Apache running".
I found this thread through a Google search, looking for a "Method to run Node.js and Apache together", but my frame is that I want to run a small Node.js-based Web-Applet in a subdirectory of an Apache hosted site.
For this particular case I went on using the 'node-fastcgi' npmjs module, and I find it a proper and even well-performing solution to run my Node.js script on the very same IP address AND port as the Apache server.

Also, note the description from the npmjs.org descripton of 'node-fastcgi':
"Create FastCGI applications in node. Near drop-in replacement for node's http module."

This means, effectively that the implementation of the server logic is not any different, so on sites which are not running an Apache the Node.js app can be run standalone using http.createServer() method from Step 4 of this Howto.

@sdesalas

This comment has been minimized.

Copy link

commented Jun 11, 2014

IPs are not cheap these days, the internet is running out of them.

@jeffmcneill

This comment has been minimized.

Copy link

commented Jun 15, 2014

IPs are very cheap, and the Internet is not running out of them. I pay $1 or $2/month for additional IP addresses on various hosts.

@nathan5x

This comment has been minimized.

Copy link

commented Aug 1, 2014

Can anybody direct me how to install NodeJS through cPanel? I have Apache server running and I want to install and run Node JS applications. Is it possible? am I in the right direction?

@jcoffland

This comment has been minimized.

Copy link

commented Aug 23, 2014

Please explain what is wrong with proxying with Apache or using fast CGI.

I see a number of problems with your proposed solution. For one, your node.js server and Apache instance will end up in different security sandboxes on the browser due to the same-origin policy. You would then need CORS or JSONP to allow Javascript code running on the two different addresses to talk to each other. Furthermore, aside from needing two IPs you also need to configure to domains. These could just be subdomains. Then there is the problem of running node.js as root as was mentioned above. All these problems considered, I don't see how this is the obvious and only reasonable solution.

@iaincollins

This comment has been minimized.

Copy link

commented Oct 6, 2014

Two IP addresses for this is very wasteful and the likes of ARIN and RIPE would not thank you for it.

Apache's Proxy module is great and can work but entirely agree not the right solution if you've a Node.js app you want to expose.

Instead, you can just bind Apache to something like localhost:8080 and your Node.js app to something like localhost:3000 and use something like HA Proxy or Varnish have it pass through different hosts or paths through to different servers, both exposed on port 80.

I use Varnish for this, with multiple of node.js, Apache and other services all exposed on port 80.

@wejn

This comment has been minimized.

Copy link

commented Apr 24, 2015

@jeffmcneill Ah, that's interesting. So the space will only be depleted when you get a failed alloc for single IPv4. Please do keep us posted.

@e70838

This comment has been minimized.

Copy link

commented Sep 4, 2015

I do not know if this is "the right way", but I strongly disagree with the agressiv post of "@tcrebbs".
He is accusing the author of this gist of running node as a root service to use reserved port 80. Of course, this is stupid to run node as root. Node can use port 80 without running as root. There are two solutions. You can either use "setcap 'cap_net_bind_service=+ep' /usr/bin/nodejs" or use iptables (see http://stackoverflow.com/questions/16573668/best-practices-when-running-node-js-with-port-80-ubuntu-linode).

In both cases, you avoid the performance penalty of apache proxy (this may be important) at the cost of an additional ip address. Instead of religions, it is better to understand the advantages and disadvantges of the different technical possibilities before choosing solutions.

@mojaray2k

This comment has been minimized.

Copy link

commented Dec 24, 2015

Hey I made a Youtube Video that implements your gist. https://www.youtube.com/watch?v=3U1AkjlWymI&feature=youtu.be

@wathmal

This comment has been minimized.

Copy link

commented Jun 14, 2016

following article also describes a way to do this without mod_rewrite on same VPS.
https://wathmal.me/blog/run-apache-with-node-js-reverse-proxy/

@yenleidong

This comment has been minimized.

Copy link

commented Dec 23, 2016

solve my problem, and @mojaray2k video implement was really clear.
we dont need to rebuild or install another mod on WHM and mod_rewrite concept, I can't take the risk if my Cpanel going error.

FYI if you want to express require module together with http module, simply using this code
/*****************************/
var app = express();
var http = require('http');
/* pur some apt.set here /
/
pur some apt.use or express static configurations here /
/
pur some apt.get here */
app.server = http.createServer(app);
app.server.listen(80, '111.111.111.111'); // change 111.111.111.111 with your reserve IP

@lancasterjones

This comment has been minimized.

Copy link

commented Apr 19, 2017

If you have apache you can add this in your Apache config file:
ProxyPass /node http://localhost:8000/
Asuming 8000 is the port where node is listening.

@AbdelhamidAhmed

This comment has been minimized.

Copy link

commented Jul 18, 2017

Thank you so much for this, I've been trying to get this to work for a long while now especially after buying a very expensive dedicated server and found myself not able to run node.js without a port because of apache.

@fdorantesm

This comment has been minimized.

Copy link

commented Sep 4, 2017

The disadvantage to use proxyPass is that you can't use host property to do something related with subdomains, base uri namespace, etc. This will be localhost:{port}

@saman2ny

This comment has been minimized.

Copy link

commented Feb 16, 2018

this wont works for https 443 port also gets blocked

@akilawickey

This comment has been minimized.

Copy link

commented Jun 5, 2018

Thank you @lancasterjones your way worked for me :-).
This can be added to apache /etc/apache2/sites-enabled/000-default.conf before the ending.

Eg

<VirtualHost *:80>
        # The ServerName directive sets the request scheme, hostname and port that
        # the server uses to identify itself. This is used when creating
        # redirection URLs. In the context of virtual hosts, the ServerName
        # specifies what hostname must appear in the request's Host: header to
        # match this virtual host. For the default virtual host (this file) this
        # value is not decisive as it is used as a last resort host regardless.
        # However, you must set it for any further virtual host explicitly.
        #ServerName www.example.com

        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html/iot-platform-frontend

        # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
        # error, crit, alert, emerg.
        # It is also possible to configure the loglevel for particular
        # modules, e.g.
        #LogLevel info ssl:warn

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        # For most configuration files from conf-available/, which are
        # enabled or disabled at a global level, it is possible to
        # include a line for only one particular virtual host. For example the
        # following line enables the CGI configuration for this host only
        # after it has been globally disabled with "a2disconf".
        #Include conf-available/serve-cgi-bin.conf
ProxyRequests on
ProxyPass /node http://localhost:8080
</VirtualHost>

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.