Using multistage docker build to create IIS + ASP.NET Core image + nanoserver

Kestrel webserver (server which serves ASP.NET core exe) does not support integrated Windows authentication and requires external proxy server to handle this. One of the those proxy servers is IIS. Problem is that there is no docker image provided by Microsoft which have IIS + ASP.NET core + nanoserver. Further complicating things are the fact that there is no easy and straightforward way to install IIS on nanoserver image which has ASP.NET core, neither it’s easy to install ASP.NET core on IIS image build on nanoserver. There is multitude articles and script which are doing little parts here and there but none provide complete solution in part due to requirement to have ASP.NET core module to be first installed on full server core image before DLLs can be extracted for use in nanoserver IIS image.

Thanks to 17.05 docker options to build multistage image this entire pretty easily accomplished with single docker file.

Dockerfile below is using 2 middleware images to pull relevant files into final image which contains ASP.NET core + IIS on top of nanoserver.

Image microsoft/aspnetcore:2.0.0-nanoserver  is used for extraction of .NET core installation.

Image microsoft\iis based off WindowsServerCore is used to install .NET core webhosting package (EXE which upon execution places required ASP.NET core module and schema into middleware container) and later extract 2 necessary files (module itself and schema file) to be used in final image.

Final image is built from 2 middleware images above with some additional configuration necessary for ASP.NET core module to work in IIS and path to DOTNET core is added to environment Path variable.

# escape=`
# Image with NET CORE installation to extract executables for final image
FROM microsoft/aspnetcore:2.0.0-nanoserver As CoreBuild
# Middleware image used to extract ASP.NET core module
From microsoft/iis as WindowsBuild
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'Continue'; $verbosePreference='Continue';"]
# Installing NET CORE webhosting in middleware image so latest module and configuration schema is extracted for final image
ADD ".\hosting.exe"
RUN start-process -Filepath .\hosting.exe -ArgumentList @('/install', '/quiet', '/norestart') -Wait
FROM microsoft/iis:nanoserver
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'Continue'; $verbosePreference='Continue';"]
RUN start-process -Filepath dism.exe -ArgumentList @('/online', '/enable-feature:IIS-WindowsAuthentication', '/ALL') -Wait
# Adding NET CORE EXE to Path environment variable
RUN setx /M PATH $($Env:PATH + ';' + $Env:ProgramFiles + '\dotnet')
#Copy dotnet core installation from middleware image
COPY –from=CoreBuild ["c:\\Program Files\\dotnet", "c:\\program files\\dotnet"]
#Copy dotnet core module from middleware image
COPY –from=WindowsBuild ["c:\\Windows\\System32\\inetsrv\\aspnetcore.dll", "c:\\Windows\\System32\\inetsrv\\"]
COPY –from=WindowsBuild ["c:\\Windows\\System32\\inetsrv\\config\\schema\\aspnetcore_schema.xml", "c:\\Windows\\System32\\inetsrv\\config\\schema\\"]
# Configure IIS to use ASPNET core module
RUN Import-Module IISAdministration; `
Start-IISCommitDelay; `
(Get-IISServerManager).GetApplicationHostConfiguration().RootSectionGroup.Sections.Add('appSettings') ; `
(Get-IISServerManager).GetApplicationHostConfiguration().GetSection('system.webServer/handlers').Overridemode = 'Allow' ; `
(Get-IISServerManager).GetApplicationHostConfiguration().RootSectionGroup.SectionGroups['system.webServer'].Sections.Add('aspNetCore'); `
(Get-IISServerManager).GetApplicationHostConfiguration().RootSectionGroup.SectionGroups['system.webServer'].Sections['aspNetCore'].OverrideModeDefault = 'Allow'; `
New-IISConfigCollectionElement (Get-IISConfigSection 'system.webServer/globalModules' | Get-IISConfigCollection) -ConfigAttribute @{'name'='AspNetCoreModule';'image'='C:\windows\system32\inetsrv\aspnetcore.dll'}; `
New-IISConfigCollectionElement (Get-IISConfigSection 'system.webServer/modules' | Get-IISConfigCollection) -ConfigAttribute @{'name'='AspNetCoreModule'}; `

view raw
hosted with ❤ by GitHub

One thought on “Using multistage docker build to create IIS + ASP.NET Core image + nanoserver

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s