【发布时间】:2020-04-28 23:03:37
【问题描述】:
我有一个构建为 x86 的 .NET Core 3.1.3 Web API 项目。它必须是 x86,因为它通过 dllimport 使用 x86 C++ DLL。在 Docker 之外,应用程序按预期运行。但是,一旦我添加了 Windows Docker 支持,它就会立即失败。我从 SO 研究中相信它失败了,因为 Microsoft 没有为 .NET Core 提供任何 x86 基础映像。默认的 Windows Docker 基础镜像当前是 mcr.microsoft.com/dotnet/core/aspnet:3.1-nanoserver-1903。
我尝试使用 mcr.microsoft.com/windows/servercore:1909 作为基础映像,但随后收到错误消息“无法启动程序:'C:\Program Files\dotnet\dotnet.exe。 '" 我认为这是因为此 exe 在所使用的基础映像中不存在。而且,对于 x86,大概需要“C:\Program Files (x86)\dotnet\dotnet.exe”。
我当前的 Dockerfile 是:
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"]
我是否正确解释了这个错误。如果不是,那是什么意思?如果是这样,如何添加支持以在此映像中构建我的 .NET Core 应用的 x86 版本?我需要以某种方式下载并运行 dotnet-runtime-3.1.3-win-x86.exe 吗?如果有,怎么做?
更新 2020 年 4 月 29 日
根据 Matt Thalman 的回答,我构建了一个自定义映像以包含 x86 版本的 .NET Core 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\dotnet.exe.'”)。为什么VS仍在尝试使用x64入口点。该项目是针对 x86 平台构建的,生成的图像看起来不错。
我基于应用程序映像创建了一个容器,并将CMDed 到其中并确认所有文件都在预期的位置,甚至从命令行运行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 运行的问题吗?
【问题讨论】:
-
我根本无法使用此图像运行 Invoke-WebRequest (mcr.microsoft.com/windows/servercore:1909)。它总是以“无法解析远程名称”而失败。然而,这个图像(mcr.microsoft.com/dotnet/framework/runtime:4.8)更好,但我无法在那里设置任何 ENV 变量。我是否错过了上述解决方案的任何更新?
标签: c# docker .net-core x86 dockerfile