Easy Way to Deploying ASP.NET Core with .NET Framework using Docker

22Nov, 2018

When working with Docker, most folks are very familiar with deploying and building Linux-based containers.  ASP.NET Core is a web framework that works great on both Windows and Linux, and can run on both the cross-platform .NET Core framework and the classic .NET Framework.  Last week, I was asked about how to package that ASP.NET Core application such that it runs on .NET Framework on a Windows-based container with IIS.  I took some time on my live-stream show and walked through the process.

The Process and Configuration

For the demo I showed on stream, we started with the default ASP.NET Core application and set it to use .NET Framework 4.7.2.  Visual Studio 2017 has support for building with .NET Core or .NET Framework versions later than 4.6.1.  When we added docker support to the project, Visual Studio created this Dockerfile by default:

#Depending on the operating system of the host machines(s) that will build or run the containers, the image specified in the FROM statement may need to be changed.
#For more information, please see https://aka.ms/containercompat
FROM AS base
WORKDIR /app
EXPOSE 80
FROM AS build
WORKDIR /src
COPY [“NetFrameworkDemo/NetFrameworkDemo.csproj”, “NetFrameworkDemo/”]
RUN dotnet restore “NetFrameworkDemo/NetFrameworkDemo.csproj”
COPY . .
WORKDIR “/src/NetFrameworkDemo”
RUN dotnet build “NetFrameworkDemo.csproj” -c Release -o /app
FROM build AS publish
RUN dotnet publish “NetFrameworkDemo.csproj” -c Release -o /app
FROM base AS final
WORKDIR /app
COPY –from=publish /app .
ENTRYPOINT [“dotnet”, “NetFrameworkDemo.dll”]

Wow… there’s a number of problems with this default file:  no reference to base Docker images and the entrypoint defined doesn’t work on Windows with IIS. This dockerfile is configured so that it builds our application inside of one container called “build” and then deploys to a runtime container called “base” and then referenced later as “final”

Let’s start cleaning this up.

  • The “build” container should be based on microsoft/dotnet-framework:4.7.2-sdk – this container has the .NET Framework build tools and it has the .NET CLI v2.1.400 installed.
  • The entrypoint should be handled by IIS, and we should only be copying our application into the IIS image.  Hmm..  let’s change the base image to microsoft/iis and change the publish step to write the application into the /inetpub/wwwroot that IIS hosts applications out of.
FROM microsoft/iis as base
FROM microsoft/dotnet-framework:4.7.2-sdk AS build
WORKDIR /src
COPY [“NetFrameworkDemo.csproj”, “NetFrameworkDemo/”]
RUN dotnet restore “NetFrameworkDemo/NetFrameworkDemo.csproj”
WORKDIR “/src/NetFrameworkDemo”
COPY . .
RUN dotnet build “NetFrameworkDemo.csproj” -c Release -o \app
FROM build AS publish
RUN dotnet publish “NetFrameworkDemo.csproj” -c Release -o \publish
FROM base AS final
WORKDIR /inetpub/wwwroot
COPY –from=publish \publish .

Great, that builds the application and deploys it to the appropriate folder for IIS.  Let’s build the container:

docker build -t netframeworkdemo:live netframeworkdemo

I then started the container with:

docker run -itdp 8000:80 netframeworkdemo:live

When I opened my browser and navigated to localhost:8000, it errored out.  No dice, no joy.

No Joy – Where’s my website?

That’s where we ended with the video stream.

What was missing?  Why wasn’t it running?

I reached out to the IIS team and asked about the problem.  Quickly they gave me a sample dockerfile that installed the missing ASP.NET Core hosting pack.  Doh!

I updated our Dockerfile and added the install process for the hosting pack and it now looks like:

# escape=`
FROM microsoft/iis as base
## Install the dotnet hosting pack
SHELL [“powershell”, “-Command”, “$ErrorActionPreference = ‘Stop’;”]
RUN `
New-Item -Type Directory C:\Setup | Out-Null ; `
Invoke-WebRequest ‘https://download.microsoft.com/download/6/E/B/6EBD972D-2E2F-41EB-9668-F73F5FDDC09C/dotnet-hosting-2.1.3-win.exe’ -UserAgent -OutFile C:/setup/dotnet-hosting-2.1.3-win.exe ; `
$process = start-process -Filepath C:/setup/dotnet-hosting-2.1.3-win.exe -ArgumentList @(‘/install’, ‘/q’, ‘/norestart’, ‘OPT_NO_RUNTIME=1’, ‘OPT_NO_SHAREDFX=1’) -Wait -PassThru ; `
`
if ($process.ExitCode -ne 0) { `
exit $process.ExitCode ; `
} `
Remove-Item -Force C:/setup/dotnet-hosting-2.1.3-win.exe
## end install
FROM microsoft/dotnet-framework:4.7.2-sdk AS build
WORKDIR /src
COPY [“NetFrameworkDemo.csproj”, “NetFrameworkDemo/”]
RUN dotnet restore “NetFrameworkDemo/NetFrameworkDemo.csproj”
WORKDIR “/src/NetFrameworkDemo”
COPY . .
RUN dotnet build “NetFrameworkDemo.csproj” -c Release -o \app
FROM build AS publish
RUN dotnet publish “NetFrameworkDemo.csproj” -c Release -o \publish
FROM base AS final
WORKDIR /inetpub/wwwroot
COPY –from=publish \publish .

That was it…  the application ran properly.

Summary

Windows containers really are just like Windows virtual machines or Windows servers.  If you find that the base Windows images don’t have what you need on them, its easy enough to run some Powershell or a Chocolatey script to install the missing components.  With this bit of additional installation, we’ve got a container image that can run .NET Framework 4.7.2 and host an ASP.NET Core application on IIS.

If you are looking for Windows ASP.NET Core hosting that support Docker, you can consider ASPHostPortal.

Easy Way to Deploying ASP.NET Core with .NET Framework using Docker
Rate this post

error: Content is protected !!