ASP.NET Core на Nano Server

Sourabh Shirhatti

Внимание

В этом руководстве используется предварительная версия опции установки Nano Server в Windows Server Technical Preview 5. Вы не сможете использовать ПО в операционной среде “live”. См. https://go.microsoft.com/fwlink/?LinkId=624232.

В этом руководстве мы развернем существующее ASP.NET Core приложение на Nano Server с запуском IIS.

Введение

Просмотрите документацию по Nano Server. Есть три способа установки Nano Server:

  1. Вы можете скачать файл Windows Server 2016 Technical Preview 5 ISO и собрать образ Nano Server
  2. Скачать Nano Server developer VHD
  3. Создать VM на Azure, используя образ Nano Server в Azure Gallery.

В этом руководстве мы будем использовать Nano Server Developer VHD из Windows Server Technical Preview 5.

Также нам понадобится результат существующего ASP.NET Core приложения. Убедитесь, что приложение запускается в процессе 64-bit.

Настройка экземпляра Nano Server

Создайте новую виртуальную машину с помощью Hyper-V, используя ранее скачанный VHD. Вам потребуется установить пароль администратора, прежде чем залогиниться. В VM консоли нажмите F11, чтобы установить пароль.

После установки локального пароля вам нужно настроить Nano Server с помощью PowerShell.

Соединение с Nano Server с помощью PowerShell

Откройте окно PowerShell, чтобы добавить экземпляр удаленного Nano Server в список TrustedHosts.

$nanoServerIpAddress = "10.83.181.14"
Set-Item WSMan:\localhost\Client\TrustedHosts "$nanoServerIpAddress" -Concatenate -Force

NOTE: Замените переменную $nanoServerIpAddress корректным IP адресом.

После добавления экземпляра Nano Server в TrustedHosts, вы можете соединиться с ним с помощью PowerShell remoting

$nanoServerSession = New-PSSession -ComputerName $nanoServerIpAddress -Credential ~\Administrator
Enter-PSSession $nanoServerSession

A successful connection results in a prompt with a format looking like: [10.83.181.14]: PS C:\Users\Administrator\Documents>

Создание файлового ресурса общего доступа

Создайте файловый ресурс общего доступа на Nano Server, так чтобы сюда можно было скопировать опубликованное приложение. Запустите следующие команды в удаленной сессии:

mkdir C:\PublishedApps\AspNetCoreSampleForNano
netsh advfirewall firewall set rule group="File and Printer Sharing" new enable=yes
net share AspNetCoreSampleForNano=c:\PublishedApps\AspNetCoreSampleForNano /GRANT:EVERYONE`,FULL

После запуска вышеуказанных команд вы должны получить доступ к ресурсу, если посетите \\<nanoserver-ip-address>\AspNetCoreSampleForNano в Windows Explorer.

Открытие порта в Firewall

Запустите следующие команды в удаленной сессии, чтобы открыть порт в firewall и прослушать TCP трафик.

New-NetFirewallRule -Name "AspNet5 IIS" -DisplayName "Allow HTTP on TCP/8000" -Protocol TCP -LocalPort 8000 -Action Allow -Enabled True

Установка IIS

Добавьте провайдер NanoServerPackage из галереи PowerShell. После установки и импортирования провайдера вы можете установить пакеты Windows.

Запустите следующие команды в сессии PowerShel, которую мы создали ранее:

Install-PackageProvider NanoServerPackage
Import-PackageProvider NanoServerPackage
Install-NanoServerPackage -Name Microsoft-NanoServer-Storage-Package
Install-NanoServerPackage -Name Microsoft-NanoServer-IIS-Package

Примечание

Установка Microsoft-NanoServer-Storage-Package требует перезагрузки.

Чтобы проверить, установлен ли IIS корректно, пройдите по http://<nanoserver-ip-address>/, и вы должны увидеть страницу с приветствием. После установки IIS по умолчанию вызывается веб сайт Default Web Site, который прослушивается по порту 80.

Установка ASP.NET Core Module (ANCM)

ASP.NET Core Module - это модуль IIS 7.5+, который отвечает за управление процессами слушателей ASP.NET Core HTTPи прокси запросов. На данный момент устанавливать ASP.NET Core Module для IIS надо вручную. Вам потребуется установить комплект .NET Core Windows Server Hosting на обычном (не Nano) компьютере. После установки комплекта вам потребуется скопировать следующие файлы в ресурс, который мы создали ранее.

На обычном (не Nano) компьютере запустите следующие команды копирования:

copy C:\windows\system32\inetsrv\aspnetcore.dll ``\\<nanoserver-ip-address>\AspNetCoreSampleForNano``
copy C:\windows\system32\inetsrv\config\schema\aspnetcore_schema.xml ``\\<nanoserver-ip-address>\AspNetCoreSampleForNano``

На компьютере с Nano вам потребуется скопировать следующие файлы из файлового ресурса. Итак, запустите следующие команды:

copy C:\PublishedApps\AspNetCoreSampleForNano\aspnetcore.dll C:\windows\system32\inetsrv\
copy C:\PublishedApps\AspNetCoreSampleForNano\aspnetcore_schema.xml C:\windows\system32\inetsrv\config\schema\

В удаленной сессии запустите следующий скрипт:

# Backup existing applicationHost.config
copy C:\Windows\System32\inetsrv\config\applicationHost.config C:\Windows\System32\inetsrv\config\applicationHost_BeforeInstallingANCM.config

Import-Module IISAdministration

# Initialize variables
$aspNetCoreHandlerFilePath="C:\windows\system32\inetsrv\aspnetcore.dll"
Reset-IISServerManager -confirm:$false
$sm = Get-IISServerManager

# Add AppSettings section 
$sm.GetApplicationHostConfiguration().RootSectionGroup.Sections.Add("appSettings")

# Set Allow for handlers section
$appHostconfig = $sm.GetApplicationHostConfiguration()
$section = $appHostconfig.GetSection("system.webServer/handlers")
$section.OverrideMode="Allow"

# Add aspNetCore section to system.webServer
$sectionaspNetCore = $appHostConfig.RootSectionGroup.SectionGroups["system.webServer"].Sections.Add("aspNetCore")
$sectionaspNetCore.OverrideModeDefault = "Allow"
$sm.CommitChanges()

# Configure globalModule
Reset-IISServerManager -confirm:$false
$globalModules = Get-IISConfigSection "system.webServer/globalModules" | Get-IISConfigCollection
New-IISConfigCollectionElement $globalModules -ConfigAttribute @{"name"="AspNetCoreModule";"image"=$aspNetCoreHandlerFilePath}

# Configure module
$modules = Get-IISConfigSection "system.webServer/modules" | Get-IISConfigCollection
New-IISConfigCollectionElement $modules -ConfigAttribute @{"name"="AspNetCoreModule"}

# Backup existing applicationHost.config
copy C:\Windows\System32\inetsrv\config\applicationHost.config C:\Windows\System32\inetsrv\config\applicationHost_AfterInstallingANCM.config

NOTE: Удалите файлы aspnetcore.dll и aspnetcore_schema.xml из файлового ресурса.

Установка фреймворка .NET Core

Если вы опубликовали портативное приложение, на целевой машине надо установить .NET Core. Выполните следующий Powershell скрипт в удаленной Powershell сессии, чтобы установить .NET Framework на Nano Server.

$SourcePath = "https://go.microsoft.com/fwlink/?LinkID=809115"
$DestinationPath = "C:\dotnet"

$EditionId = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' -Name 'EditionID').EditionId

if (($EditionId -eq "ServerStandardNano") -or
    ($EditionId -eq "ServerDataCenterNano") -or
    ($EditionId -eq "NanoServer") -or
    ($EditionId -eq "ServerTuva")) {

    $TempPath = [System.IO.Path]::GetTempFileName()
    if (($SourcePath -as [System.URI]).AbsoluteURI -ne $null)
    {
        $handler = New-Object System.Net.Http.HttpClientHandler
        $client = New-Object System.Net.Http.HttpClient($handler)
        $client.Timeout = New-Object System.TimeSpan(0, 30, 0)
        $cancelTokenSource = [System.Threading.CancellationTokenSource]::new()
        $responseMsg = $client.GetAsync([System.Uri]::new($SourcePath), $cancelTokenSource.Token)
        $responseMsg.Wait()
        if (!$responseMsg.IsCanceled)
        {
            $response = $responseMsg.Result
            if ($response.IsSuccessStatusCode)
            {
                $downloadedFileStream = [System.IO.FileStream]::new($TempPath, [System.IO.FileMode]::Create, [System.IO.FileAccess]::Write)
                $copyStreamOp = $response.Content.CopyToAsync($downloadedFileStream)
                $copyStreamOp.Wait()
                $downloadedFileStream.Close()
                if ($copyStreamOp.Exception -ne $null)
                {
                    throw $copyStreamOp.Exception
                }
            }
        }
    }
    else
    {
        throw "Cannot copy from $SourcePath"
    }
    [System.IO.Compression.ZipFile]::ExtractToDirectory($TempPath, $DestinationPath)
    Remove-Item $TempPath
}

Публикация приложения

Скопируйте публикационную версию приложения в файловый ресурс общего доступа.

Вам потребуется внести изменения в web.config, чтобы указать, куда извлечь dotnet.exe. Как вариант, вы можете добавить в путь dotnet.exe.

Вот пример того, как может выглядеть web.config, если dotnet.exe не находится в пути:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <handlers>
      <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
    </handlers>
    <aspNetCore processPath="C:\dotnet\dotnet.exe" arguments=".\AspNetCoreSampleForNano.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="true" />
  </system.webServer>
</configuration>

Запустите следующие команды в удаленной сессии, чтобы создать новый сайт в IIS для опубликованного приложения. В этом скрипте для простоты используется DefaultAppPool. Еще см. Application Pools.

Import-module IISAdministration
New-IISSite -Name "AspNetCore" -PhysicalPath c:\PublishedApps\AspNetCoreSampleForNano -BindingInformation "*:8000:"

.NET Core CLI на Nano Server

Если вы используете Nano Server Technical Preview 5 с .NET Core CLI, вам потребуется скопировать все DLL файлы из c:\windows\system32\forwarders в c:\windows\system32.

Если вы используете dotnet publish, скопируйте все DLL файлы с c:\windows\system32\forwarders в директорию с опубликованным приложением.

Если ваша сборка Nano Server Technical Preview 5 обновлена, повторите этот процесс, поскольку DLL тоже обновлены.

Запуск приложения

К опубликованному веб приложению можно получить доступ в браузере по http://<nanoserver-ip-address>:8000. Если вы настроили логирование, как описано в Log creation and redirection, то должны увидеть логи по C:\PublishedApps\AspNetCoreSampleForNano\logs.

Поделись хорошей новостью с друзьями!
Следи за новостями!