Setting up Apache to Serve Angular and Act as a Reverse Proxy for Kestrel

· Alex Peters

Introduction

Today we'll figure out how to configure Apache to serve your Angular application and act as a reverse proxy server for Kestrel. This guide is intended for Linux (specifically Ubuntu), but with slight adjustments, it's applicable to Windows as well.

Setting up Apache VirtualHost

First, go to /etc/apache2/sites-available and create a new configuration file, say example.conf.
Now open the file and add a new virtual host:


<VirtualHost *:80>
    ServerName example.com
    DocumentRoot "/var/www/frontend"
    ErrorLog ${APACHE_LOG_DIR}/example.com-error.log
    CustomLog ${APACHE_LOG_DIR}/example.com-access.log combined
</VirtualHost>

Granting Access to Angular Build Directory

Next, we’ll add a directory directive to allow access:


<Directory "/var/www/frontend">
    Require all granted
</Directory>

Require all granted allows everyone to access the Angular frontend files publicly. Without this, Apache might block access by default.

Configuring the Reverse Proxy to Kestrel

Now, configure Apache to forward API calls to the Kestrel server:


ProxyPreserveHost On
ProxyPass /api/ http://localhost:5000/
ProxyPassReverse /api/ http://localhost:5000/

<Location /api>
    Require all granted
</Location>
            

Enabling URL Rewriting

Finally, we configure URL rewriting to handle Angular routing properly:


<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
    RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d [OR]
    RewriteCond %{REQUEST_URI} ^/api/
    RewriteRule ^ - [L]
    RewriteRule ^ /index.html [L]
</IfModule>
            

If you find Apache config syntax a little convoluted, here is some pseudocode that makes it easier to understand:


if (File.Exists(Path.Combine(documentRoot, requestUri.TrimStart('/')))
    || Directory.Exists(Path.Combine(documentRoot, requestUri.TrimStart('/')))
    || requestUri.StartsWith("/api/", StringComparison.OrdinalIgnoreCase)) {}
else
{
    requestUri = "/index.html";
}
            

Final Apache Configuration

Your final example.conf should look like this:


<VirtualHost *:80>
    ServerName example.com
    DocumentRoot "/var/www/frontend"

    <Directory "/var/www/frontend">
        Require all granted
    </Directory>

    ProxyPreserveHost On
    ProxyPass /api/ http://localhost:5000/
    ProxyPassReverse /api/ http://localhost:5000/

    <Location /api>
        Require all granted
    </Location>

    <IfModule mod_rewrite.c>
        RewriteEngine On
        RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
        RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d [OR]
        RewriteCond %{REQUEST_URI} ^/api/
        RewriteRule ^ - [L]
        RewriteRule ^ /index.html [L]
    </IfModule>

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
            

Enabling the Site and Reloading Apache

Once you’re done with the configuration, run:


sudo a2ensite example.conf
sudo systemctl reload apache2
            

Now Apache will serve your Angular frontend and forward API requests correctly to your backend running on Kestrel.