Read Part 3 of this article series to create Asp.Net Core application deployment package.
Overview
As we continue our learning, we will use the deployment package created using the techniques discussed in previous part and host the application. Though Asp.Net Core application has new a webserver called Kestrel, it is required that the Asp.Net Core application should be deployed behind a full-fledged webservers like IIS, Nginx or Apache as reverse proxy. In next section, we will understand this hosting model in detail.
Asp.Net Core Hosting Environment
Before delving into the details of hosting the app, it will be better if we understand the basics of Asp.Net Core hosting environment. As we know, Asp.Net Core applications will come with its own in-process webserver called Kestrel. Traditionally, all we did is use the IIS webserver to host our Asp.Net application which has taken care of every aspect of our application hosting. Since, Asp.Net Core platform is developed as cross platform framework, the Asp.Net Core app should be able to run under other common webservers like Nginx, Apache, etc. apart from IIS. Like IIS, different webservers has different start-up mechanisms. This means that the Asp.Net Core app should adopt different start-up mechanisms based on the webserver it is targeted. Instead of adopting different start-up for different webservers, Asp.Net Core has included a light weight, cross platform webserver called Kestrel to have consistent start-up behaviour across platforms. But, Kestrel webserver does not have all the capabilities of a full-fledged webservers like IIS, Nginx, Apache, etc. to take care of all aspect of hosting by itself. For example, Kestrel did not have the capability to share same port number for different web sites while webservers like IIS do with the help of host header value. It is an in-memory webserver which does not have a management console, not as secured as IIS, etc.
Read the quick start article Learn Kestrel Webserver in 10 Minutes to understand more about Kestrel webserver.
So, the recommended deployment option for Asp.Net Core application is to use the webservers like IIS, Nginx, and Apache as a reverse proxy and host the application using Kestrel. This means the webservers (IIS, Nginx, and Apache) will get the request from users and it will just forward the request to Kestrel using HTTP for processing and the get the response back from Kestrel to send it back to users.
To understand, why it is called reverse proxy we should first understand what a proxy does. There is a proxy in every network that intercepts request from users before forwarding to outside (server or website). The proxy has an authority to deny connection to a destination based on pre-defined rules set by the network admin. In general, a proxy intercepts and moderates the out bound request from a network user like below,
Similarly, a reverse proxy intercepts request from a user in outside network and forwards them to a configured destination inside a network. Thus, a webserver reverse proxy (IIS, Nginx, and Apache) intercepts inbound request and forwards it to an Asp.Net Core App (Kestrel) similar to below.
The communication between reverse proxy server and Kestrel can happen in plain http since the communication is internal. This means we can restrict the use https on the IIS site and kestrel can just receive the request using plain http. Thus, by hosting Asp.Net Core app behind these full-fledged webservers as reverse proxy gives us everything we need for hosting the app and on other hand, we can also use the capabilities of the full-fledged webservers for our applications.
With these information, let’s move ahead and see how we can host Asp.Net Core app behind IIS. The .Net Core SDK when installed it provides a native IIS module called Asp.Net Core Module to forward request to Asp.Net Core app. This can be seen in the IIS Management console under Modules.
The Asp.Net Core applications runs in a separate process as opposed to traditional Asp.Net application where the application itself runs under IIS worker process. The new process model looks like,
Configuring Application to Use Core Module
To make the IIS website to use Asp.Net Core IIS module, we need to include Web.Config file in our application root with following configuration setting,
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\ASPNETCoreVS2017Demo.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" />
</system.webServer>
</configuration>
Note – Publishing you project with Visual Studio will automatically include this web.config file in the output directory.
As you can see above, the above configuration will make the IIS to handle all the requests to any path (*) by Asp.Net Core module. The Asp.Net Core module will forward it to Kestrel and get back the response after processing. This clearly indicates that IIS worker process (w3wp.exe) does not process our request instead it just runs the Asp.Net Core module to forward the request to Asp.Net Core App as seen in the process model diagram above.
It is now the responsibility of Asp.Net Core module to load the application when the first request arrives and make sure the application is running to process the incoming requests. When there is a failure in application, it is the responsibility of the core module to re-run the application to service the incoming requests. Read here to know more about configuration settings of Asp.Net Core module.
The application level configuration for setting up Kestrel and IIS integration is done in the Main() method under Program.cs class. Let’s examine this method to understand how the above process wiring is done.
public class Program
{
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.UseApplicationInsights()
.Build();
host.Run();
}
}
Unlike, traditional Asp.Net project the Asp.Net Core project is a console application with Main method and it is the entry point to our application. When the Asp.Net Core Module calls the application first time, this method executes and it sets up the hosting environment for request processing. The WebHostBuilder object uses Fluent Builder pattern (Method Chaining) to configure the application to take up request processing.
The UseKestrel() method setup the Kestrel webserver and starts listening to a default port 5000 for incoming request. You can change the default port by calling WebHostBuilder.UseUrls("http://localhost:5500") method. The UseIISIntegration() method integrates the application with IIS Asp.Net Core module. The Startup class for setting the Asp.Net Core pipeline is configured by calling UseStartup<Startup>() method as seen in the above code. Finally, calling Run() actually starts the application with all the configuration we provided by chaining the WebHostBuilder methods.
Steps to Host Asp.Net Core App behind IIS as Reverse Proxy
-
Open IIS Manager. Type inetmgr in RUN and press Enter.
-
Right Click Sites Node and Select “Add Website..” Specify a site name and configure the physical path where you have published the release files. For avoiding conflict with the default site, I have specified the port 8000. Click Ok.
This will create a new website and add a new Application Pool with same name as of the site. Since, IIS did not host our site we can set the Application Pool to not use .NET. This will give some performance benefit. To do this, got to Application Pools Node, right click the app pool and select “Basic Settings..”. Change .Net CLR Version to “No Managed Code” like below.
That’s it, we are done with hosting a simple Asp.Net Core app by using IIS as reverse proxy. Let’s understand hosting Asp.Net Core App using Nginx and Apache in another article.
Open browser and visit http://localhost:8000/. You will see the application coming up.
Happy Coding!!
Further Reading
- Read Difference Between Asp.Net and Asp.Net Core for a side by side difference.
- To know more about the new features in Asp.Net Core, read Breaking Changes and New Features of Asp.Net Core MVC.