Setting up Apache Reverse Proxy and Port Forwarding for a Node.js App

Photo by T K on Unsplash

Setting up Apache Reverse Proxy and Port Forwarding for a Node.js App

ยท

2 min read

I acquired an Ubuntu 20.04 virtual private server some time ago, planning to host my math-themed web app there. I now wanted to forward requests to my Node.js API app (behind the port 3100) from the /math-api/ URL. I'm using Apache as the HTTP server, so I had to set up a reverse proxy.

I actually had done this before with HTTP on another server. I now wanted to use HTTPS. So, I first added the following configuration to the configuration file in /etc/apache2/sites-available:

<VirtualHost *:80>
        # ...snip

        ProxyPass /math-api https://www.mkkekkonen.fi:3100/
        ProxyPassReverse /math-api https://www.mkkekkonen.fi:3100/
</VirtualHost>

This wasn't working, however. I found that out by running:

sudo service apache2 restart

I got the following error:

Job for apache2.service failed because the control process exited with error code.
See "systemctl status apache2.service" and "journalctl -xe" for details.

Next, I ran:

sudo apachectl configtest

It outputted:

AH00526: Syntax error on line 35 of /etc/apache2/sites-enabled/000-default.conf:
Invalid command 'ProxyPass', perhaps misspelled or defined by a module not included in the server configuration
Action 'configtest' failed.
The Apache error log may have more information.

The reason was that I had not enabled the Apache HTTP proxy module. After some Googling, I found out that I had to run:

sudo a2enmod proxy_http

The previous command enables the proxy_http module. The sudo service apache2 restart command worked now.

However, the configuration was not yet working, as I got a "Not Found" error when navigating to, e.g., the mkkekkonen.fi/math-api/page URL. I tried adding the ProxyPreserveHost On directive to the virtual host configuration, but that did not work either.

I again Googled around and finally figured out the correct configuration. I added the following to the default configuration file in /etc/apache2/sites-available:

<VirtualHost *:80>
        # ...snip

        ServerName mkkekkonen.fi

        SSLProxyEngine On
        ProxyPreserveHost On
        ProxyPass /math-api/ http://www.mkkekkonen.fi:3100/
        ProxyPassReverse /math-api/ http://www.mkkekkonen.fi:3100/

        SSLCertificateFile /path/to/certificate.pem
        SSLCertificateKeyFile /path/to/key/file.pem
</VirtualHost>

...and the same to the SSL configuration file in the same directory:

<VirtualHost *:443>
        # ...snip

        ServerName mkkekkonen.fi

        SSLProxyEngine On
        ProxyPreserveHost On
        ProxyPass /math-api/ http://www.mkkekkonen.fi:3100/
        ProxyPassReverse /math-api/ http://www.mkkekkonen.fi:3100/

        SSLCertificateFile /path/to/certificate.pem
        SSLCertificateKeyFile /path/to/key/file.pem
</VirtualHost>

After restarting Apache again, I finally got JSON output when navigating to the public mkkekkonen.fi/math-api/page URL. ๐ŸŽ‰

Sources:

Apache HTTP Server: mod_proxy
Simplified Guide: How to enable or disable Apache modules
Ask Ubuntu: Apache not able to restart
Server Fault: Why am I getting an "Invalid command 'ProxyPass'" error when I start my Apache 2.2 server?
TecAdmin: How to Setup Apache As Frontend Proxy for Node.js
Stack Overflow: How to configure apache to forward https requests

ย