Deploy ASP.NET Core to IIS & How ASP.NET Core Hosting Works

Deploy ASP.NET Core to IIS & How ASP.NET Core Hosting Works | Best and cheap ASP.NET Core 1.0 hosting. In this article, we will review how to deploy an ASP.NET Core application to IIS. Deploying an ASP.NET Core app to IIS isn’t complicated, but ASP.NET Core hosting is a little different than ASP.NET.

How to Configure Your ASP.NET Core App For IIS

The first thing you will notice when creating a new ASP.NET Core project is they are actually console applications. Your project now contains a Program.cs file just like a console app would have and it contains the following code:

What is the WebHostBuilder?

All ASP.NET Core applications require a WebHost object that essentially serves as the application and web server. WebHostBuilder is used to configure and create the WebHost. You will normally see UseKestrel() and UseIISIntegration() in the WebHostBuilder setup code.

What do these do?

  • UseKestrel() – This registers the IServer interface for Kestrel as the server that will be used to host your application. In the future, there could be other options, including WebListener which will be Windows only.
  • UseIISIntegration() – This tells ASP.NET that IIS will be working as a reverse proxy in front of Kestrel. This then specifies some settings around which port Kestrel should listen on, forwarding headers, and other details.

If you are planning to deploy your application to IIS, UseIISIntegration() is required

What is AspNetCoreModule?

You may have noticed that ASP.NET Core projects create a web.config file. This is only used when deploying your application to IIS. It registers the AspNetCoreModule as an HTTP handler.

Default web.config for ASP.NET Core:

If you are planning to deploy your application to IIS, UseIISIntegration() is required

Default web.config for ASP.NET Core:

AspNetCoreModule handles all incoming traffic to IIS and acts as the reverse proxy that knows how to hand the traffic off to your ASP.NET Core application. You can view the source code of it on GitHub. It also ensures that your web application is running. It is responsible for starting your process up.

Install .NET Core Windows Server Hosting Bundle

Before you deploy your application, you need to install the .NET Core hosting bundle for IIS. This will install the .NET Core runtime, libraries, and the ASP.NET Core module for IIS.

After installing it, you may need to do a “net stop was /y” and “net start w3svc” to ensure all the changes are picked up for IIS.

Steps to Deploy ASP.NET Core to IIS

Before you deploy, you need to make sure that WebHostBuilder is configured properly to use Kestrel and IIS. Your web.config should also exist and look similar to our example above.

Step 1: Publish to a File Folder


Step 2: Copy Files to Preferred IIS Location

Now you need to copy your publish output to where you want the files to live. If you are deploying to a remote server, you may want to zip up the files and move to the server. If you are deploying to a local dev box, you can copy them locally.

For my example, I am copying the files to C:\inetpub\wwwroot\AspNetCore46

You will notice that with ASP.NET core there is no bin folder and it potentially copies over a ton of different .NET dlls. Your application may also be an EXE file if you are targeting the full .NET Framework. My little sample project had over 100 dlls in the output.


Step 3: Create Application in IIS

First, create a new IIS Application Pool. You will want to create one under the .NET CLR version of “No Managed Code“. Since IIS only works as a reverse proxy, it isn’t actually executing any .NET code.

Second, create your new application under your existing IIS Site, or create a new IIS site. Either way, you will want to pick your new IIS Application Pool and point it at the folder you copied your ASP.NET publish output files to.


Step 4: Load Your App!

At this point, your application should load just fine. If it does not, check the output logging from it. Within your web.config file you define how IIS starts up your ASP.NET Core process. Enable output logging by setting stdoutLogEnabled=true and you may also want to change the log output location as configured in stdoutLogFile. Check out the example web.config before to see where they are set.

Advantages of Using IIS with ASP.NET Core Hosting

Microsoft recommends using IIS with any public facing site for ASP.NET core hosting. IIS provides additional levels of configurability, management, security, logging, and many other things. Check out my blog post about Kestrel vs IIS to see a whole matrix of feature differences. It goes more in depth about what Kestrel is and why you need both Kestrel & IIS.

One of the big advantages to using IIS is the process management. IIS will automatically start your app and potentially restart it if a crash were to occur. If you were running your ASP.NET Core app as a Windows Service or console app, you would not have that safety net there to start and monitor the process for you.

.NET Core And SQL Server In Linux Docker Containers

.NET Core And SQL Server In Linux Docker Containers | Best and cheap ASP.NET core hosting. Throughout the years, we have been using ASP.NET and SQL Server mainly on Windows. Now the times have changed! You can now develop the same ASP.NET (with more optimized runtime and libraries) apps with the same SQL Server Database Engine on Linux and this is what I want to show you here.

To make things more interesting, I will take Docker, a leading container technology platform, into account for this demo. We have an Azure Linux VM (Ubuntu 16.04) where Docker is installed. We will spin up an ASP.NET Core container and a SQL Server container in a separate Docker user-defined network, accessing the application container from the VM’s public IP address and SQL Server container from SSMS on our local Windows Machine.


Getting Started

I have a Linux Ubuntu 16.04 VM in Azure with Docker installed. I will SSH into the machine and generate a default ASP.NET Core 1.0 LTS project with SQL Server Entity Framework Core provider installed. You can do so manually either using dotnet CLI or Yeoman Generators.

The default ASP.NET Core project uses Identity for authentication\authorization. Identity, in turn, depends upon an EFCore provider which is in our case SQL Server.

Now, we do the following 3 important things here.

  1. Pull down the official Microsoft SQL Server image from Docker Hub
  2. Change the Connection String of the application such that it points to the SQL Server Docker container
  3. Dockerize the application

Pull down the official SQL Server Docker image from the terminal as,

docker pull microsoft/mssql-server-linux:latest

Next, change the connection string of the ASP.NET Core application in the appsettings.json file using Vim or Nano editor at the root as,

Notice the Server name in the connection string. It should not be the localhost if you want to run the application inside the Docker container as in our case. The Server name must match with the SQL Server custom container name when we run it. This is how Services are discovered by the Docker Engine.

Also, make sure that the “Trusted_Connection” is set to false as it forces the integrated security inside the Linux which is not supported.

Now finally, create the Dockerfile to build the Docker image of our application at the root as,

touch Dockerfile

With the contents,

And build the image with any name (aspnetcoreapp in our case) by the typing in the terminal.

docker build -t aspnetcoreapp .

It will start restoring the NuGet packages, set up the environment and build the Docker image for the application.

We now have the SQL Server and ASP.NET Core Docker images. The next thing we need to do is to configure the Azure VM’s Network Security Group (NSG) to open port 80 to allow HTTP traffic from the Internet and the port 1433 to allow our local SQL Server Management Studio to connect to the SQL Server container running inside the Linux VM.

My Linux VM is provisioned using ARM model this is why we need to configure the NSG which was created with the VM. If you used ASM model, configure the VM’s endpoint instead.

To do this, we add Inbound Security Rules for port 80 and 1433. So go to NSG blade => Inbound security rules => Add inbound security rule, type any formal names and open the ports 80 and 1433 as.


This is all we have to do. Now we have 2 Docker images and configured the NSG of the NIC attached with the VM.

Spinning up the containers

Spin up the SQL Server Container

To spin up the SQL Server container, type in the terminal as,

docker run -e ‘ACCEPT_EULA=Y’ -e ‘SA_PASSWORD=Br0ckLesnar!’ -p 1433:1433 -d –name sqlinux –network=isolated_network microsoft/mssql-server-linux

Notice the name of the container. As said earlier, this must match with the server name given in the connection string of the web app settings. Also notice that we must place these running containers inside a separate Docker network. If we don’t specify a network, it will run inside the default network and automatic service discovery does not work in the default network to create a separate Docker network type.

And, use this network for your containers.

Spin up the ASP.NET Core Container

To run the ASP.NET Core container, simply type.

docker run -p 80:5000 -d –name webapp –network=isolated_network aspnetcoreapp

We now have the application and database containers running and they are interacting with each other. To test this, browse to the public IP address or DNS name of your Linux VM on your local machine’s browser and you will see that the application is up and running.


Go to the Register page and try to register a user.


And you can see that the user is successfully created in SQL Server running inside the Docker Container.


Connecting Windows SSMS with Docker SQL Server

Now we will use our local SQL Server tool, called SQL Server Management Studio (SSMS),  to connect the SQL Server instance running inside the Docker container inside the Azure VM. Remember, we opened the port 1433 in the NSG attached to the NIC of the VM. So open the SSMS and type the IP Address of the VM with port (with format [ip_address, port]) inside the Server name section, use the SQL Server Authentication option, type the user SA and type the password we used when we spun the SQL Server container.


We see that the Server is connected — now run a SQL query against one of the tables  created by Identity in the database and you will see that the record has been successfully added and displaying in the SSMS.



We saw how we connect an application container and a database container with service discovery feature of Docker Engine. I did not mount any volume to the SQL Server container nor did I use any Docker Volume plugin to make it even more productive so this is stateless by default. Using the same technique for production use case is not recommended. The idea was to provide a step by step guide to build a simple 3-tier application using Docker containers.