.NET, NGINX, Kestrel, and React with a Reverse Proxy on Linux Ubuntu

A bare-bones, 5 step tutorial.

Image for post
Image for post

Background: A Use Case More Complex than the Tutorial

So I just spent a few days banging my head against my desk 😡, trying to get my .NET 5.0 application with a React SPA to live under a separate URL via a reverse proxy. While the official Microsoft tutorial for hosting .NET on Linux is very detailed, it’s only for a single site running at port 80, where the root of the site is assumed to be the .NET app itself. They also leave all ports as their default values in their tutorial.

Assumed Environment (Important: Please Read!)

For this tutorial, we’re going to assume we already have a running website called mysite.com.

Step 1 — Extend the NGINX Configuration for mysite.com to Include a Reverse Proxy

Your extended configuration can be as simple as:

location /my-first-dotnet-app/ {  proxy_pass http://localhost:1234/;}
sudo service nginx restart

Step 2 — Configure the Default Kestrel Port for the .NET Application

As mentioned above, we are using port number 1234 to run our application. This requires a change in the configuration of our .NET application.

"Kestrel": {  "Endpoints": {    "Http": {      "Url": "http://localhost:1234"    }  }}

Step 3 — Remove HTTPS Redirect from the .NET App

I mentioned for this example we assume that mysite.com already has https setup (and NGINX is handling the HTTPS redirect, so we don’t need .NET for that). Hop into Startup.cs and delete the following line:

app.UseHttpsRedirection();

Step 4 — Setup React for the Correct Path with the package.json Homepage Directive

This one is the biggest gotcha. You can do everything else correct and still get frustrating 404s and the dreaded white screen.

"homepage": "https://mysite.com/my-first-dotnet-app",

Step 5 — Create a Service File to Run the .NET Project

When we run a build with:

dotnet publish --configuration Release
MyFirstDotnetApp/bin/Release/net5.0/publish/
Description=My First Dotnet App[Service]WorkingDirectory=/var/www/MyFirstDotnetApp/bin/Release/net5.0/publish/ExecStart=/usr/bin/dotnet /var/www/MyFirstDotnetApp/bin/Release/net5.0/publish/MyFirstDotnetApp.dllRestart=always# Restart service after 10 seconds if the dotnet service crashes:RestartSec=10KillSignal=SIGINTSyslogIdentifier=my-first-dotnet-appUser=rootEnvironment=ASPNETCORE_ENVIRONMENT=ProductionEnvironment=DOTNET_PRINT_TELEMETRY_MESSAGE=false[Install]WantedBy=multi-user.target
/etc/systemd/system/my-first-dotnet-app.service
sudo systemctl enable my-first-dotnet-app.service
sudo systemctl start my-first-dotnet-app.service
  1. Override default Kestrel port to the port of our choosing (1234)
  2. Remove HTTPS redirection from the .NET app
  3. Add correct homepage path, mysite.com/my-first-dotnet-app/ to package.json of React SPA for proper SPA asset locating
  4. Create and run a Kestrel service file for the .NET app

Questions, Comments, Something Didn’t Work?

Let me know in the comments!

https://wheelscreener.com https://chrisfrew.in 👨‍💻Full Stack Software Engineer 🏠Austria/USA 🍺Homebrewer ⛷🏃‍Outdoorsman

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store