Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 96 You must be signed in to star a gist
  • Fork 18 You must be signed in to fork a gist
  • Save stagas/754303 to your computer and use it in GitHub Desktop.
Save stagas/754303 to your computer and use it in GitHub Desktop.
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.end('Hello, world!');

server.listen(80, '');

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

Copy link

Good idea..

Copy link

grisevg commented Dec 1, 2011

what if you don't have 2 ip addresses?

Copy link

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

Copy link

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

Copy link

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!

Copy link

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:

Copy link

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.

Copy link

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?

Copy link

@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!

Copy link

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

Copy link

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

Copy link

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

Copy link

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.

Copy link

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?

Copy link

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.

Copy link

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.

Copy link

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

Copy link

e70838 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

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.

Copy link

Hey I made a Youtube Video that implements your gist.

Copy link

wathmal commented Jun 14, 2016

following article also describes a way to do this without mod_rewrite on same VPS.

Copy link

yenleidong 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, ''); // change with your reserve IP

Copy link

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.

Copy link

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.

Copy link

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}

Copy link

this wont works for https 443 port also gets blocked

Copy link

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


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

        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

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

Copy link

Created tutorial on How to deploy nodejs application subdirectory level in apache ubuntu

Copy link

amarjit-singh commented Jul 18, 2021

what if you don't have 2 ip addresses?

Then follow this article

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment