Setup NodeJS with Apache ProxyPass on Raspberry Pi

Setup NodeJS with Apache ProxyPass on Raspberry Pi 2 and 3. This allows multiple NodeJS apps to run in the backend but under a single hostname/domain with different virtual subfolder path for each of them.

Installing NodeJS

Referring to NodeJS guide on how to download, I followed the instructions on Debian-based linux distributions.

If you have installed NodeJS from the raspberrypi.org repository, I suggest that you purge them to get back to clean slate state:

sudo apt-get purge npm
sudo apt-get purge nodejs

You will need to install cURL if you do not have it:

sudo apt-get install -y curl

Next, run the following command to download and install NodeJS 8.x:

curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
sudo apt-get install -y nodejs

To find out the version installed:

node -v

Hello World test

Run a simple Hello World web server on NodeJS to verify that it works.

File: server.js

var http = require('http');
var port = 3000;
http.createServer(function (req, res) {
    res.writeHead(200, { 'Content-Type': 'text/plain' });
    res.end('Hello World\n');
}).listen(port, "localhost");

Run the app and return to console:

node server.js &

The Process ID (PID) will be shown. Take note of that ID, it will be different per run.

To verify, use cURL to query the node:

curl http://localhost:3000/

The output should be: Hello World

Running alongside Apache

NodeJS runs on its own port as defined by the server.js script. Normally, we do not want this exposed to public. Instead, most would prefer to have http://<domain>/api/ instead of http://<domain>:3000/.

Assuming Apache 2.x is your web server, you could edit the virtual host config to proxy the requests on that path to your NodeJS instance.

Firstly, enable the Apache proxy_http module:

sudo a2enmod proxy
sudo a2enmod proxy_http
sudo service apache2 restart

Next, add the following lines into vhost config:

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

For the vhost changes to take effect:

sudo service apache2 reload

To verify, use cURL to query the node again but this time via path on Apache web server:

curl http://localhost/api/

The output should be: Hello World