CheapWindowsHosting.com | Best and cheap ASP.NET Core hosting. In this post we will show you how to running ASP.NET Core with IIS on Nano server.
First you need to install IIS on Nano.
Currently, both HttpPlatformHandler and Asp.Net Core Kestrel host requires Reverse Forwarders package to be installed on the Nano machine. Reverse Fowarders can be installed offline (machine turned off) or online (machine running).
Offline, Reverse Forwarders can be installed by passing –ReverseForwarders parameters when calling New-NanoServerImage cmdlet.
e.g. New-NanoServerImage -MediaPath f:\ -BasePath .\Base -TargetPath .\Nano1.vhd -GuestDrivers -Packages Microsoft-NanoServer-IIS-Package -ReverseForwarders
Online, Reverse Forwarders can be installed by calling dism on the relevant package:
In this case, C:\packages is a local directory that I created where I copied the Packages folder from the Nano Server media installation location.
After installing Reverse Forwarders package (whether offline or online), verify that IIS and Reverse Forwarders are correctly installed by running ‘dism /online /get-packages’.
You should see the Feature and Language packs for Microsoft-NanoServer-IIS-Package and Microsoft-OneCore-ReverseForwarders-Package.
At this time, the install for HttpPlatformHandler on Nano is manual.
Nano is 64 bit only (no WOW), so you’ll need to install the latest x64 version of HttpPlatformHandler (http://www.iis.net/downloads/microsoft/httpplatformhandler) on a regular (not Nano) machine.
Once you have x64 bit version of HttpPlatformHandler installed on your regular (not Nano) machine, there are 2 files which we’ll need to copy to the Nano machine:
On the Nano machine you’ll need to copy those 2 files to the respective locations (dll->inetsrv, schema file->inetsrv\config\schema)
You can execute the steps below in a remote PowerShell session to the Nano machine.
Note that the below steps works on a clean system, but is not meant to be idempotent. If you run this multiple times it will add multiple entries and you will run into problems!
If you end up in a bad state, you can find backups of the applicationHost.config file at %systemdrive%\inetpub\history.
Import-Module IISAdministration
$sm = Get-IISServerManager
# Add AppSettings section (for Asp.Net Core)
$sm.GetApplicationHostConfiguration().RootSectionGroup.Sections.Add("appSettings")
# Unlock handlers section
$appHostconfig = $sm.GetApplicationHostConfiguration()
$section = $appHostconfig.GetSection("system.webServer/handlers")
$section.OverrideMode="Allow"
# Add httpPlatform section to system.webServer
$sectionHttpPlatform = $appHostConfig.RootSectionGroup.SectionGroups["system.webServer"].Sections.Add("httpPlatform")
$sectionHttpPlatform.OverrideModeDefault = "Allow"
# Add to globalModules
$globalModules = Get-IISConfigSection "system.webServer/globalModules" | Get-IISConfigCollection
New-IISConfigCollectionElement $globalModules -ConfigAttribute @{"name"="httpPlatformHandler";"image"="%SystemRoot%\system32\inetsrv\httpPlatformHandler.dll"}
# Add to modules
$modules = Get-IISConfigSection "system.webServer/modules" | Get-IISConfigCollection
New-IISConfigCollectionElement $modules -ConfigAttribute @{"name"="httpPlatformHandler"}
$sm.CommitChanges()
You can skip this section if you already did the PowerShell steps above.
I recommend following the PowerShell steps, although if you absolutely must edit the IIS applicationHost.config file to enable HttpPlatformHandler then these are the steps.
Open up c:\windows\system32\inetsrv\applicationHost.config
(if you are using Powershell ISE v5 you can do this using ‘psedit c:\windows\system32\inetsrv\applicationHost.config’)
Under <configSections> add
<configSections>
<section name="appSettings" />
In system.webServer section, unlock handlers from Deny to Allow
<section name="handlers" overrideModeDefault="Allow" />
In system.webServer section, add new httpPlatform section
<section name="httpPlatform" overrideModeDefault="Allow" />
</sectionGroup>
Add the following to globalModules
<add name="httpPlatformHandler" image="%SystemRoot%\system32\inetsrv\httpPlatformHandler.dll" />
</globalModules>
Add the following to Modules
<add name="httpPlatformHandler" />
</modules>
First, make sure that your Asp.Net Core application is built targeting coreclr and x64.
This is very important as any other combination will not work on Nano.
After building for coreclr/x64 you will need to copy the whole application to the Nano machine – in this example I’m using c:\HelloAspNetCore.
Next I will setup a new Site pointing to c:\HelloAspNetCore\wwwroot using port 8000 (for simplicity we will go with Default App Pool)
There are no problems running the Asp.Net Core site on default port 80, though in a testing environment I like to separate the Asp.Net Core app from the default website, so that it’s easier to troubleshoot when something goes wrong (e.g. so you can verify that the default IIS site still works fine).
Using IIS PowerShell:
Import-module IISAdministration
New-IISSite -Name "AspNetCoreSite" -PhysicalPath c:\HelloAspNetcore\wwwroot -BindingInformation "*:8000:"
Creating the site manually (omit if you already created using PowerShell above) by editing c:\windows\system32\inetsrv\applicationHost.config:
<sites>
<site name="Default Web Site" id="1">
<application path="/">
<virtualDirectory path="/" physicalPath="%SystemDrive%\inetpub\wwwroot" />
</application>
<bindings>
<binding protocol="http" bindingInformation="*:80:" />
</bindings>
</site>
<site name="AspNetCoreSite" id="2">
<application path="/">
<virtualDirectory path="/" physicalPath="C:\HelloAspNetCore\wwwroot" />
</application>
<bindings>
<binding protocol="http" bindingInformation="*:8000:" />
</bindings>
</site>
… rest of xml…
</sites>
The next step is to open up port 8000 in the firewall.
New-NetFirewallRule -Name "AspNetCore" -DisplayName "HTTP on TCP/8000" -Protocol tcp -LocalPort 8000 -Action Allow -Enabled True
I have followed the steps, but it doesn't work 🙁
It gets a PERMISSION DENIED; I found it in the app /logs directory (included below).
Does it need an additional ICACL somewhere? I don't know under what security context it runs...
I think I saw somewhere it could need permission for the port it runs on. If so, how do we grant permissions on that port?
Microsoft.AspNet.Server.Kestrel.Networking.UvException: Error -4092 EACCES permission denied
at Microsoft.AspNet.Server.Kestrel.Networking.Libuv.Check(Int32 statusCode)
at Microsoft.AspNet.Server.Kestrel.Networking.UvTcpHandle.Bind(ServerAddress address)
at Microsoft.AspNet.Server.Kestrel.Http.TcpListener.CreateListenSocket()
at Microsoft.AspNet.Server.Kestrel.Http.Listener.<>c__DisplayClass5_0.<StartAsync>b__0(Object _)