How to Host ASP.NET Core App on Linux with Nginx Webserver

In this article, we are going to learn how to Host ASP.NET Core Application on Linux VM in Azure with Nginx Web server in simple steps.

The version of the Linux operating system: – Ubuntu 18.04
Web Server: – Nginx
ASP.NET Core Version: – 3.1
Hosting: – on Azure Linux VM with Ubuntu Operating System

Table of Contents

  • Getting Started with Hosting ASP.NET Core on Linux
  • Project structure
  • Configure a reverse proxy server in the application
  • Configure Method in Startup Class
  • Supported distributions
  • Creating Azure VM
  • Connecting to Linux VM Using PuTTY
  • Step 1 (Register the Microsoft Product key as trusted)
  • Step 2 (Install .Net Core runtime)
  • Step 3 (Publishing Application)
  • Step 4 (Copying Application to Linux VM)
  • Step 5 (Install Nginx)
  • Step 6 (Starting Nginx Server)
  • Step 7 Check the server status if running
  • Step 8 Configure Nginx
  • Step 9 Replace Server tag which in default file with below content
  • Step 10 Check Syntax of the Default file
  • Step 11 Reload Server
  • Step 12 (Creating Folder in www folder)
  • Step 13 (Creating service file)
  • Step 14 Enable the service
  • Step 15 Start the service
  • Step 16 Verify Service is running
  • Step 17 Output
  • Step 18 Troubleshoot if you are not able to see the Hosted application in the browser

Getting Started with Hosting ASP.NET Core on Linux

We are going to create a new application with Name Webnix for demo as shown below.

Next, we are going to set Project Name Webnix and location. In last part, we are going to choose .Net Core framework and ASP.NET Core Version 3.1 as the framework for application and few advance settings for such as configuring https and enabling docker we are not going to enable docker settings for this project.

Now finally click on create button to create a project.

Project structure

The project structure generated according to the configuration.

Configure a reverse proxy server in the application

After creating project next, we are going to make changes in Configure method in Startup class we are going to add UseForwardedHeaders middleware.

app.UseForwardedHeaders(new ForwardedHeadersOptions
{
      ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});

Configure Method in Startup Class

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{

    app.UseForwardedHeaders(new ForwardedHeadersOptions
    {
        ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
    });

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
       
        app.UseHsts();
    }
    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
    });
}

Supported distributions

Distributions that are supported for hosting .Net Core 3.1.
https://docs.microsoft.com/en-us/dotnet/core/install/linux-ubuntu

Creating Azure Linux VM

In this part, we are going to create Linux Virtual Machine on Azure with Image of Ubuntu Server 18.04 LTS.
You can choose your subscription which you have next in Resource group if you have existing resource group then you can select that or create a new resource for this demo, I have made new resources group Host-VM-RG
Then in Instance details, we are going to name Virtual machine as VMLinux You can choose the name of VM as you want. Next, to select a region to depend upon your choice, I am going to choose Central US. Operation System for VM (image) we are going to choose Ubuntu Server 18.04 LTS – Gen1 which is supported for hosting .Net Core 3.1.

Next to choosing Size of Virtual Machine according to you need for the demo we don’t require a large machine that why I have chosen Standard_B2s instance which has 2 vCPU(s) and 4GB RAM.

In authentication type we are going to choose is Password for using it we need to provide Username, Password and Confirm Password.

Inbound port rules section Public inbound ports we are going to choose Allow selected ports and in Select inbound ports we are going to select port 80 (HTTP) and port 22 (SSH).

With this configuration just click on Review + Create button to create you VM will take some time for deployment.

Connecting to Linux VM Using PuTTY

For connecting to Linux Virtual Machine, we are going to use the PuTTY URL for downloading putty https://www.putty.org/.

To get Public IP address to connect to you VM just click on Home Menu from sidebar then you can Recent resources from that choose recently Create Virtual Machine you will see a similar screen as shown below.

Let’s start PuTTY for connecting to Virtual Machine

Enter your public IP address in Host Name and Port will be 22 as shown in the above screenshot and click on Open button to connect.

Enter your username and password which you have set while creating Virtual Machine.

After connecting terminal, we are going to run some installation in it.

Step 1 (Register the Microsoft Product key as trusted)

We are going to run this command in terminal.

wget https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb

Step 2 (Install .Net Core runtime)

In this step we are going to install .NET Core Runtime allows you to run apps that were made with .NET Core.

sudo apt-get update; \
sudo apt-get install -y apt-transport-https && \
sudo apt-get update && \
sudo apt-get install -y aspnetcore-runtime-3.1 

Step 3 (Publishing Application “Webnix”)

In this step, we are going to publish an application to the folder and copy that folder to VM.
For publishing application just right click on the web application (Webnix) and select publish from Menu.
We are going publish the application to the local folder we are going to choose Folder option.

Published files

After publishing, we need to copy files to Linux Virtual Machine for doing that we are going to use WinSCP tool.

Step 4 (Copying Application to Linux VM)

In this step, we are going to copy that folder to Linux Virtual Machine for doing that we are going to use WinSCP.

URL to Download WinSCP: –  https://winscp.net/eng/index.php

Step 5 (Install Nginx)

In this step, we are going to install Nginx Web server.

sudo apt-get install nginx

Next, we have installed Nginx Web Server now we are going to start Nginx server.

Step 6 (Starting Nginx Server)

In this step, we are going to Start Nginx server

sudo service nginx start

Step 7 Check the server status if running

Check the status of the started Nginx server

sudo service nginx status

Step 8 Configure Nginx

Here we are going configure Nginx as a reverse proxy to forward requests to your ASP.NET Core Application for doing that we need to modify /etc/nginx/sites-available/default Open it in a text editor, and replace the contents with the following:

nano /etc/nginx/sites-available/default

Opens default file in a text editor as shown below.

Step 9 Replace Server tag which in default file with below content

server {
    listen        80;
    server_name   example.com *.example.com;
    location / {
        proxy_pass         http://localhost:5000;
        proxy_http_version 1.1;
        proxy_set_header   Upgrade $http_upgrade;
        proxy_set_header   Connection keep-alive;
        proxy_set_header   Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
    }
}

Nginx configuration file forwards incoming public traffic from port 80 to port 5000.

Step 10 Check Syntax of the Default file

sudo nginx -t

Step 11 Reload Server

Reload server after we have made changes in the configuration file.

sudo nginx -s reload

Step 12 (Creating Folder in www folder)

In step 3 we have copied files to /home/azureuser/publish/ folder now we are going copy those files to /var/www/publishapplication/ folder. Before copying, we are going to create a folder.
www folder is where we keep web application which will be available to the internet.

sudo mkdir -p /var/www/publishapplication/publish/

mkdir -p command
With the help of mkdir -p command, you can create subdirectories of a directory. It will create a parent directory first if it doesn’t exist.
But if it already exists, then it will not print an error message and will move further to create sub-directories.

Copy files to newly created folder /var/www/publishapplication/ Publish folder.

cp -r /home/azureuser/publish/ /var/www/publishapplication/

cp -r command
Option ‘r’ with the copy command can be used to copy a directory including all its content from a source directory to the destination directory.

View after copying files to a new folder.

Step 13 (Creating service file)

Creating an NGINX systemd service file.

sudo nano /etc/systemd/system/kestrel-Webnix.service
[Unit]
Description=Example My ASP.NET Core Application running on Ubuntu

[Service]
WorkingDirectory=/var/www/publishapplication/publish
ExecStart=/usr/bin/dotnet /var/www/publishapplication/publish/Webnix.dll
Restart=always
# Restart service after 10 seconds if the dotnet service crashes:
RestartSec=10
KillSignal=SIGINT
SyslogIdentifier=dotnet-example
User=www-data
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false

[Install]
WantedBy=multi-user.target

Step 14 Enable the service

sudo systemctl enable kestrel-Webnix.service

Step 15 Start the service

sudo systemctl start kestrel-Webnix.service

Step 16 Verify Service is running

sudo systemctl status kestrel-Webnix.service

After verifying service is working now let’s check application is running or not by copying public IP address in the browser.

Step 17 Output

Step 18 Troubleshoot if you are not able to see the Hosted application in the browser

If the application is not running just check azure inbound port rules if 80 port exists or not if not then add 80 port with TCP protocol.

Reference

https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/linux-nginx?view=aspnetcore-3.1

https://www.javatpoint.com/linux-cp-r

By Saineshwar Bageri

I am Microsoft MVP | C# Corner MVP | Code Project MVP | FULL STACK .NET Developer and working on .Net Web Technology (Asp.net, Asp.net Core,.Net Core, C#, Sqlserver, MVC, Windows, Console Application, javascript, jquery, json, ORM Dapper) and also a freelance developer.