I have found it annoying to have my static web site sitting in the web root (i.e. port 80) and the rest server on another port. In order to have everything pointing back to port 80 we can set up a reverse proxy in our server directive.

Reverse Proxy

Whereas a regular proxy takes requests from the “inside” and decides how/where to pass them “out”, a reverse proxy takes requests from the “outside” and decides how/where to pass them “in”. If we can somehow identify requests destined for the node app then we can configure apache/nginx to forward them on.

You can launch a node server in the background and redirect the output into a log file like so:

nohup npm start 1> webapp-out.log 2>&1 &

Assuming that your app is using port 3000 (and the port is exposed), your endpoint is now listening for requests on port 3000 of your server.

In our example we’ll identify requests that should be forward on to our app by prepending /api to each of the endpoints. For example if we had two endpoints /message and /post we would change them to /api/message and /api/post respectively. This can be thought of as a mount point for our app. Now we can tell the web server to forward on all requests that begin with /api

Apache

1) For Apache we’ll have to enable mod_proxy and mod_proxy_http

sudo a2enmod proxy
sudo a2enmod proxy_http

2) Then add the following four lines to the directives. On my server (Ubuntu0416) that’s in /etc/apache2/sites-available/

ProxyRequests Off
ProxyPreserveHost On

ProxyPass /api http://localhost:3000
ProxyPassReverse /api http://localhost:3000

3) Restart apache2:
sudo service apache2 restart

Now you can call your app by prepending /api to the url of your endpoint!

NGINX

1) NGINX doesn’t have anything like Apache’s ProxyPassReverse. Instead we’ll add this to the directives. On my server (Ubuntu0416) that’s in /etc/nginx/sites-available/

location /api {
        proxy_set_header X-Forwarded-Host $host:$server_port;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://localhost:3000;
}

2) Restart nginx:
sudo service nginx restart

Now you can call your app by prepending /api to the url of your endpoint!

A few side notes:

1) If you want all requests going to your node app you can leave out the mount point and simply use /:

Apache

ProxyRequests Off
ProxyPreserveHost On

ProxyPass / http://localhost:3000
ProxyPassReverse / http://localhost:3000

NGINX

location / {
        proxy_set_header X-Forwarded-Host $host:$server_port;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://localhost:3000;
}

2) If you don’t want to modify your node app you can use a rewrite rule to strip out the mount point from the request. You’d still need to call the endpoint like /api/message but then the directive can rewrite the request to /message and pass that on to your app.

Apache

coming soon…

NGINX

location /api {
        proxy_set_header X-Forwarded-Host $host:$server_port;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        rewrite ^/api(.*) $1 break;
        proxy_pass http://localhost:3000;
}

Much of this info came from the this github gist and nginx.com

Leave a Reply

Your email address will not be published. Required fields are marked *