How to run Apache and NodeJS based sites on the same server with Varnish


While developing Battlefield 3 Web Commander, I wanted to keep it on my VPS where I was already running Apache.

Of course I had the option of putting it in a non-standard port like 8080, but it wouldn’t be nice if the URL would be The second option was ordering an extra IP address from Linode. That would’ve cost me a bit each month, so I didn’t really want to do that either.

The third option turned out to be pretty easy: Use Varnish.

Here’s how I did it…

Step 1: Put your servers on non-80 ports

First, we need to put Apache on some other port than 80. Simply change the Listen option in Apache’s config.

Let’s say Apache goes to port 6001 for this example.

The node application will also need to run on some other port than 80. Let’s put it to port 6002.

Step 2: Configure Varnish on port 80

First, find your Varnish config file. On Ubuntu, you can probably find it at /etc/default/varnish


Make sure the DAEMON_OPTS uses port 80 in the -a flag as follows:

DAEMON_OPTS="-a :80 \
             -T localhost:6082 \
             -f /etc/varnish/default.vcl \
             -S /etc/varnish/secret \
             -s malloc,256m"

Or, if you use the advanced configuration, set VARNISH_LISTEN_PORT to 80.

Step 3: Set up Varnish proxying to Apache and Node

Open your varnish VCL file, most likely it is /etc/varnish/default.vcl

You will need to set up backends for all your servers here. In my case, I will set up backends “apache” and “node”, as follows:

backend apache {
    .host = "";
    .port = "6001";

backend node {
    .host = "";
    .port = "6002";

Next, we need to define the vcl_recv sub to route between these backends. This goes after the backend definitions in the VCL file:

sub vcl_recv {
    if( == "") {
        set req.backend = apache;

    if( == "") {
        set req.backend = node;

All we need to do is check what the host in the request is: If the domain used is, the request will be proxied to Apache, and for, to Node.

If you want to use a single domain, you could use subdomains to check which backend to use as well. In my case, I have an additional subdomain which I use to access my development node instance.

Step 4

There is no Step 4.


By using Varnish on port 80, we can pretty easily have any number of other servers serving content so that it seems that all of it is on port 80 when it really isn’t.

This of course is not the only thing Varnish can do. You can set up caching and all sorts of stuff to it, but for that you probably should look at the Varnish manual