Как запустить приложение. NET Core 3.1.3 x86 в Docker - PullRequest
0 голосов
/ 29 апреля 2020

У меня есть. NET Core 3.1.3 проект веб-API, который построен как x86. Это должна быть версия x86, потому что она использует библиотеку x86 C ++ через dllimport. За пределами Docker приложение работает как положено. Тем не менее, он сразу перестает работать, как только я добавляю поддержку Windows Docker. Я полагаю, что из SO исследований это не удается, потому что Microsoft не предоставляет базовый образ x86 для. NET Core. Базовым образом Windows Docker по умолчанию в настоящее время является mcr.microsoft.com/dotnet/core/aspnet:3.1-nanoserver-1903.

Я пытался использовать mcr.microsoft.com/ Windows / ServerCore: 1909 в качестве базового образа, но затем я получаю сообщение об ошибке «Невозможно запустить программу:« C: \ Program Files \ dotnet \ do tnet .exe. »« Я предполагаю, что это потому, что это exe не существует на используемом базовом изображении. И, предположительно, для x86 "C: \ Program Files (x86) \ dotnet \ do tnet .exe" действительно потребуется.

Мой текущий файл Docker:

FROM mcr.microsoft.com/windows/servercore:1909 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/windows/servercore:1909 AS build
WORKDIR /src
COPY ["WAPTCoreWebService/WAPTCoreWebService.csproj", "WAPTCoreWebService/"]
RUN dotnet restore "WAPTCoreWebService/WAPTCoreWebService.csproj"
COPY . .
WORKDIR "/src/WAPTCoreWebService"
RUN dotnet build "WAPTCoreWebService.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "WAPTCoreWebService.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "WAPTCoreWebService.dll"]

Правильно ли я интерпретирую эту ошибку? Если нет, что это значит? Если да, то как мне добавить поддержку для создания x86-версии моего основного приложения. NET в этом образе? Нужно ли как-то скачивать и запускать do tnet -runtime-3.1.3-win-x86.exe? Если да, то как?

ОБНОВЛЕНИЕ 4/29/2020

Основываясь на ответе Мэтта Талмана, я создал собственное изображение для включения версии x86. NET Основной SDK. Файл Docker выглядит следующим образом:

# escape=`

# Installer image
FROM mcr.microsoft.com/windows/servercore:1909 AS installer

SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]

# Retrieve .NET Core SDK
RUN $dotnet_sdk_version = '3.1.201'; `
    Invoke-WebRequest -OutFile dotnet.zip https://dotnetcli.azureedge.net/dotnet/Sdk/$dotnet_sdk_version/dotnet-sdk-$dotnet_sdk_version-win-x86.zip; `
    $dotnet_sha512 = '48aa1afaf7a52effb367bbb14a66e2c3bf8da468025795daf0fa0d18e3b9650ba3bd23800c9965a4d4ec1d891afecbce51b2487730f1b0d6040ee7cb73a15ec6'; `
    if ((Get-FileHash dotnet.zip -Algorithm sha512).Hash -ne $dotnet_sha512) { `
        Write-Host 'CHECKSUM VERIFICATION FAILED!'; `
        exit 1; `
    }; `
    `
    Expand-Archive dotnet.zip -DestinationPath dotnet; `
    Remove-Item -Force dotnet.zip

# Install PowerShell global tool
RUN $powershell_version = '7.0.0'; `
    Invoke-WebRequest -OutFile PowerShell.Windows.x64.$powershell_version.nupkg https://pwshtool.blob.core.windows.net/tool/$powershell_version/PowerShell.Windows.x64.$powershell_version.nupkg; `
    $powershell_sha512 = '1980da63a4f6017235e7af810bfda66be8fa53d0475d147a8219a36c76a903af99adb6cd5309e3dadc610389ae3525bca1ca2d30e7a991640e924334fd4e4638'; `
    if ((Get-FileHash PowerShell.Windows.x64.$powershell_version.nupkg -Algorithm sha512).Hash -ne $powershell_sha512) { `
        Write-Host 'CHECKSUM VERIFICATION FAILED!'; `
        exit 1; `
    }; `
    `
    \dotnet\dotnet tool install --add-source . --tool-path \powershell --version $powershell_version PowerShell.Windows.x64; `
    \dotnet\dotnet nuget locals all --clear; `
    Remove-Item -Force PowerShell.Windows.x64.$powershell_version.nupkg; `
    Remove-Item -Path \powershell\.store\powershell.windows.x64\$powershell_version\powershell.windows.x64\$powershell_version\powershell.windows.x64.$powershell_version.nupkg -Force

# SDK image
FROM mcr.microsoft.com/windows/servercore:1909

ENV `
    # Enable detection of running in a container
    DOTNET_RUNNING_IN_CONTAINER=true `
    # Enable correct mode for dotnet watch (only mode supported in a container)
    DOTNET_USE_POLLING_FILE_WATCHER=true `
    # Skip extraction of XML docs - generally not useful within an image/container - helps performance
    NUGET_XMLDOC_MODE=skip `
    # PowerShell telemetry for docker image usage
    POWERSHELL_DISTRIBUTION_CHANNEL=PSDocker-DotnetCoreSDK-NanoServer-1909

# In order to set system PATH, ContainerAdministrator must be used
USER ContainerAdministrator
RUN setx /M PATH "%PATH%;C:\Program Files (x86)\dotnet;C:\Program Files\powershell"
USER ContainerUser

COPY --from=installer ["/dotnet", "/Program Files (x86)/dotnet"]

COPY --from=installer ["/powershell", "/Program Files/powershell"]

# Trigger first run experience by running arbitrary cmd
RUN dotnet help

Это прекрасно работает, и команда dotnet help в конце выполняется правильно.

Я изменил Dockerfile приложения, чтобы использовать этот пользовательский образ в качестве Базовое изображение, и это также построить хорошо. Когда я запускаю это из Visual Studio 2019, я получаю ту же ошибку, что и выше («Невозможно запустить программу: 'C: \ Program Files \ dotnet \ do tnet .exe.'»). Почему VS все еще пытается использовать точку входа x64. Проект создается для платформы x86, и получающиеся изображения выглядят нормально.

Я создал контейнер на основе образа приложения и CMD добавил в него и подтвердил, что все файлы были там, где они ожидались. и даже запустил dotnet applicationName.dll из командной строки и приложение запустилось ОК.

Когда я пытаюсь запустить из Visual Studio, он пытается запустить образ с помощью:

docker run -dt -v "C:\Users\Valued Customer\onecoremsvsmon\16.5.0102.0:C:\remote_debugger:ro" -v "C:\Users\Valued Customer\AppData\Roaming\Microsoft\UserSecrets:C:\Users\ContainerUser\AppData\Roaming\Microsoft\UserSecrets:ro" -v "C:\Users\Valued Customer\AppData\Roaming\ASP.NET\Https:C:\Users\ContainerUser\AppData\Roaming\ASP.NET\Https:ro" -e "ASPNETCORE_URLS=https://+:443;http://+:80" -e "ASPNETCORE_ENVIRONMENT=Development" -e "ASPNETCORE_LOGGING__CONSOLE__DISABLECOLORS=true" -P --name WAPTCoreWebService_1 --entrypoint C:\remote_debugger\x64\msvsmon.exe waptcorewebservice /noauth /anyuser /silent /nostatus /noclrwarn /nosecuritywarn /nofirewallwarn /nowowwarn /fallbackloadremotemanagedpdbs /timeout:2147483646 /LogDebuggeeOutputToStdOut

Точка входа указывает на приложение x64 (msvsmon.exe). Может ли это быть проблемой при запуске из VS?

Ответы [ 2 ]

0 голосов
/ 05 мая 2020

Это несовершенный ответ, но мне удалось получить x86. NET Базовый веб-API, который зависит от VC ++ x86 DLL и работает на Azure Kubernetes Service. В основном у меня есть три этапа:

  1. Создание собственного образа на основе mcr.microsoft.com/windows/servercore:ltsc2019, в котором добавляется C ++ Redistributable 2015 x86;
  2. Создается другое изображение на основе 1., который добавляет. NET Core x86 SDK и;
  3. Окончательное изображение создается на основе 2., который добавляет код моего приложения.

Три файла Docker включены ниже. Далее я собираюсь объединить это в один Dockerfile.

Добавить C ++ Redist x86: waptx86custom

Примечание. Я извлек копию Redist exe из своего собственного Azure, но вы также можете просто включить его в ту же папку, что и ваш Dockerfile, и ДОБАВИТЬ его оттуда.

FROM mcr.microsoft.com/windows/servercore:ltsc2019 AS base

# Installing Microsoft Visual C++ 2015 x86 Redistributable.
ADD https://lqsts.blob.core.windows.net/temp/vc_redist_2015_3.x86.exe C:/vc_redist.x86.exe
RUN C:\vc_redist.x86.exe /install /norestart /quiet /log vc_log.txt

Добавить. NET Core SDK x86: waptx86corecustom

# escape=`

# Installer image
FROM acswebwapt.azurecr.io/waptx86custom AS installer

# Apply latest patch
RUN curl -fSLo patch.msu http://download.windowsupdate.com/c/msdownload/update/software/updt/2020/01/windows10.0-kb4534119-x64_a2dce2c83c58ea57145e9069f403d4a5d4f98713.msu `
    && mkdir patch `
    && expand patch.msu patch -F:* `
    && del /F /Q patch.msu `
    && DISM /Online /Quiet /Add-Package /PackagePath:C:\patch\windows10.0-kb4534119-x64.cab `
    && rmdir /S /Q patch

ENV COMPLUS_NGenProtectedProcess_FeatureEnabled 0

RUN \Windows\Microsoft.NET\Framework64\v4.0.30319\ngen uninstall "Microsoft.Tpm.Commands, Version=10.0.0.0, Culture=Neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=amd64" `
    && \Windows\Microsoft.NET\Framework64\v4.0.30319\ngen update `
    && \Windows\Microsoft.NET\Framework\v4.0.30319\ngen update

SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue'; $verbosePreference='Continue';"]

# Retrieve .NET Core SDK
RUN $dotnet_sdk_version = '3.1.201'; `
    Invoke-WebRequest -OutFile dotnet.zip https://dotnetcli.azureedge.net/dotnet/Sdk/$dotnet_sdk_version/dotnet-sdk-$dotnet_sdk_version-win-x86.zip; `
    $dotnet_sha512 = '48aa1afaf7a52effb367bbb14a66e2c3bf8da468025795daf0fa0d18e3b9650ba3bd23800c9965a4d4ec1d891afecbce51b2487730f1b0d6040ee7cb73a15ec6'; `
    if ((Get-FileHash dotnet.zip -Algorithm sha512).Hash -ne $dotnet_sha512) { `
        Write-Host 'CHECKSUM VERIFICATION FAILED!'; `
        exit 1; `
    }; `
    `
    Expand-Archive dotnet.zip -DestinationPath dotnet; `
    Remove-Item -Force dotnet.zip

# Install PowerShell global tool
RUN $powershell_version = '7.0.0'; `
    Invoke-WebRequest -OutFile PowerShell.Windows.x64.$powershell_version.nupkg https://pwshtool.blob.core.windows.net/tool/$powershell_version/PowerShell.Windows.x64.$powershell_version.nupkg; `
    $powershell_sha512 = '1980da63a4f6017235e7af810bfda66be8fa53d0475d147a8219a36c76a903af99adb6cd5309e3dadc610389ae3525bca1ca2d30e7a991640e924334fd4e4638'; `
    if ((Get-FileHash PowerShell.Windows.x64.$powershell_version.nupkg -Algorithm sha512).Hash -ne $powershell_sha512) { `
        Write-Host 'CHECKSUM VERIFICATION FAILED!'; `
        exit 1; `
    }; `
    `   
    \dotnet\dotnet tool install --add-source . --tool-path \powershell --version $powershell_version PowerShell.Windows.x64; `
    \dotnet\dotnet nuget locals all --clear; `
    Remove-Item -Force PowerShell.Windows.x64.$powershell_version.nupkg; `
    Remove-Item -Path \powershell\.store\powershell.windows.x64\$powershell_version\powershell.windows.x64\$powershell_version\powershell.windows.x64.$powershell_version.nupkg -Force


# SDK image
FROM acswebwapt.azurecr.io/waptx86custom

ENV `
    # Enable detection of running in a container
    DOTNET_RUNNING_IN_CONTAINER=true `
    ASPNETCORE_URLS=http://+:443;http://+:80 `
    # Enable correct mode for dotnet watch (only mode supported in a container)
    DOTNET_USE_POLLING_FILE_WATCHER=true `
    # Skip extraction of XML docs - generally not useful within an image/container - helps performance
    NUGET_XMLDOC_MODE=skip `
    # PowerShell telemetry for docker image usage
    POWERSHELL_DISTRIBUTION_CHANNEL=PSDocker-DotnetCoreSDK-NanoServer-1909

# In order to set system PATH, ContainerAdministrator must be used
USER ContainerAdministrator
RUN setx /M PATH "%PATH%;C:\Program Files (x86)\dotnet;C:\Program Files\powershell"
USER ContainerUser

COPY --from=installer ["/dotnet", "/Program Files (x86)/dotnet"]

COPY --from=installer ["/powershell", "/Program Files/powershell"]

# Trigger first run experience by running arbitrary cmd
RUN dotnet help

Добавить приложение

FROM acswebwapt.azurecr.io/waptx86corecustom AS base

WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM acswebwapt.azurecr.io/waptx86corecustom AS build

WORKDIR /src
COPY ["WAPTCoreWebService/WAPTCoreWebService.csproj", "WAPTCoreWebService/"]
RUN dotnet restore "WAPTCoreWebService/WAPTCoreWebService.csproj"
COPY . .
WORKDIR "/src/WAPTCoreWebService"
RUN dotnet build "WAPTCoreWebService.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "WAPTCoreWebService.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "WAPTCoreWebService.dll"]
0 голосов
/ 29 апреля 2020

Да, ваша интерпретация верна. Базовый образ Windows не имеет установленного ядра. NET. Документация по установке NET Core в образе Docker находится здесь: https://github.com/dotnet/dotnet-docker/blob/master/samples/snippets/installing-dotnet.md.

...