Configure Apache with Node.js application on AWS Ubuntu 18.04

A ‘web server’ can refer to either the hardware (the computer) or the software (the computer application) that helps to deliver content that can be accessed through the Internet. The primary function of a web server is to deliver web pages on the request to clients. This means delivery of HTML documents and any additional content that may be included by a document, such as images, style sheets, and scripts.

Node.js is a platform built on Chrome’s JavaScript runtime for building fast, scalable network applications. It uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices. It is a fantastic server-side javascript solution and one of it’s common examples is building an asynchronous HTTP web server. The only problem that we face while integrating Node into a shared host is that the host already has a web server listening on port 80, probably on Apache and it’s already serving your existing content.

What if I tell you that there is a way to make Nodejs server use another port, but then you have to point people to something like http://www.example.com:8080/ instead of http://www.example.com/. Now, you already know what is wrong with this picture. The former URL doesn’t look presentable like the latter, isn’t it? Let’s look at a better method to do this in a transparent way without affecting the URLs or the existing content being served.

It’s a fact that we can’t configure Node.js and Apache to listen on the same port, hence we’ll have to config Apache to act as a reverse proxy and pass the request to the node.js application for a specific URL. A reverse proxy is a proxy server which retrieves resources on behalf of the client from one or more servers. The client need not know about all those different app servers. They request proxy server on specific URL with over HTTP and proxy server finds out where to look ( in Servers ) to serve that request.

How to do this?

Consider the following scenarios :

  1. Infrastructure contains 3 different app servers running on separate ports.
  2. Accepts requests and returns requests.

Firstly, we install Apache2 and node.js on our Ubuntu server :

sudo apt-get update
sudo apt-get install apache2 nodejs

Next thing we need to proxy all requests incoming on port 80 through the URL of a node.js application to the running local node.js process. For this, we need to install/enable mod_proxy and mod_proxy_http modules on the Apache server :

a2enmod proxy
a2enmod proxy_http

So now the exciting part begins. We need to configure the Apache server to proxy requests to node.js applications. We’ll then configure a VirtualHost for this :

#/etc/apache2/sites-available/abcd.conf
<VirtualHost *:80>
ServerAdmin webmaster@localhost
ServerName mySite
ServerAlias www.abcd.com
DocumentRoot /var/www/html/abcd
<Directory />
Options -Indexes +FollowSymLinks
AllowOverride None
Require all granted
</Directory>
ProxyRequests Off
ProxyPreserveHost On
ProxyVia Full
<Proxy *>
Require all granted
</Proxy>
<Location /nodejsApp>
ProxyPass http://127.0.0.1:8080
ProxyPassReverse http://127.0.0.1:8080
</Location>
ErrorLog ${APACHE_LOG_DIR}/error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

In this configuration, we first see that every request will be routed to our web site which code pages is found in the directory /var/www/html/abcd. Next we have defined a reverse proxy so that a request to the http://www.abcd.com/nodejsAppli will be proxy to a local node.js application running on port 8080. Next, we’ll have to enable this new site configuration and we’ll disable the default one.

sudo a2ensite mySite.conf
sudo a2dissite 000-default.conf

Similarly, we can configure multiple apps using separate ports. The idea is quite simple, we use different ports to configure multiple apps without having to change the original URL.