Setting up Apache Reverse Proxy and Port Forwarding for a Node.js App
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