基于自定义基础镜像创建ASP.NET Core容器时Docker报错求助
制作了包含Java、Python、VC++及.NET等运行依赖的Windows基础镜像,基于该镜像构建ASP.NET Core Web API应用镜像,镜像构建无异常且依赖与代码均已正确复制,但运行容器时出现错误。
运行容器时的错误信息
>docker run -d -p 4000:80 --name newappcontainer6 newappimage:6.0 eec248d2f4e9b3aac693382a293f950f0458d0d3ae49030fd558a95c0ee45adc docker: Error response from daemon: container eec248d2f4e9b3aac693382a293f950f0458d0d3ae49030fd558a95c0ee45adc encountered an error during hcsshim::System::CreateProcess: failure in a Windows system call: The system cannot find the file specified. (0x2) [Event Detail: Provider: 00000000-0000-0000-0000-000000000000] [Event Detail: Provider: 00000000-0000-0000-0000-000000000000] [Event Detail: onecore\vm\compute\management\orchestration\vmhostedcontainer\processmanagement.cpp(173)\vmcomputeagent.exe!00007FF6E59A9FAB: (caller: 00007FF6E595E19A) Exception(2) tid(398) 80070002 The system cannot find the file specified. CallContext:[\Bridge_ProcessMessage\VmHostedContainer_ExecuteProcess] Provider: 00000000-0000-0000-0000-000000000000].
使用的Dockerfile
基础镜像Dockerfile
FROM mcr.microsoft.com/windows/servercore:ltsc2019-amd64 AS installer #install vc++ COPY VC_redist.x64.exe . RUN c:\VC_redist.x64.exe /install /passive /norestart /log out.txt #install Python SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] WORKDIR C:/temp/Python #RUN New-Item C:/temp -ItemType Directory; New-Item C:/data -ItemType Directory; ENV PYTHON_VERSION 3.10.4 ENV PYTHON_RELEASE 3.10.4 RUN $url = ('https://www.python.org/ftp/python/{0}/python-{1}-amd64.exe' -f $env:PYTHON_RELEASE, $env:PYTHON_VERSION); \ Write-Host ('Downloading {0} ...' -f $url); \ [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; \ Invoke-WebRequest -Uri $url -OutFile 'python.exe'; \ \ Write-Host 'Installing ...'; \ # https://docs.python.org/3.10.4/using/windows.html#installing-without-ui Start-Process python.exe -Wait \ -ArgumentList @( \ '/quiet', \ 'InstallAllUsers=1', \ 'TargetDir=C:\Python310', \ 'PrependPath=1', \ 'Shortcuts=0', \ 'Include_doc=0', \ 'Include_pip=0', \ 'Include_test=0' \ ); \ \ #the installer updated PATH, so we should refresh our local value $env:PATH = [Environment]::GetEnvironmentVariable('PATH', [EnvironmentVariableTarget]::Machine); \ \ Write-Host 'Verifying install ...'; \ Write-Host ' python --version'; python --version; \ \ Write-Host 'Removing ...'; \ Remove-Item python.exe -Force; \ \ Write-Host 'Complete.' # https://github.com/pypa/get-pip ENV PYTHON_GET_PIP_URL https://github.com/pypa/get-pip/raw/d59197a3c169cef378a22428a3fa99d33e080a5d/get-pip.py ENV PYTHON_GET_PIP_SHA256 421ac1d44c0cf9730a088e337867d974b91bdce4ea2636099275071878cc189e RUN Write-Host ('Downloading get-pip.py ({0}) ...' -f $env:PYTHON_GET_PIP_URL); \ [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; \ Invoke-WebRequest -Uri $env:PYTHON_GET_PIP_URL -OutFile 'get-pip.py'; \ Write-Host ('Verifying sha256 ({0}) ...' -f $env:PYTHON_GET_PIP_SHA256); \ if ((Get-FileHash 'get-pip.py' -Algorithm sha256).Hash -ne $env:PYTHON_GET_PIP_SHA256) { \ Write-Host 'FAILED!'; \ exit 1; \ }; \ \ Write-Host ('Installing pip ...'); \ python get-pip.py \ --disable-pip-version-check \ --no-cache-dir \ ; \ Remove-Item get-pip.py -Force; \ \ Write-Host 'Verifying pip install ...'; \ pip --version; \ \ Write-Host 'Complete.' #install Java MAINTAINER Zulu Enterprise Container Images <azul-zulu-images@microsoft.com> RUN setx PACKAGE zulu-8-azure-jdk_8.58.0.13-8.0.312-win_x64.msi RUN setx PACKAGE_DIR zulu-8/8u312 RUN setx /m JAVA_HOME "C:\temp\Zulu\zulu-8" RUN setx /m JAVA_HOME "C:\temp\Zulu\zulu-8\bin" RUN powershell -Command [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12;(new-object System.Net.WebClient).DownloadFile('https://repos.azul.com/azure-only/zulu/packages/zulu-8/8u312/zulu-8-azure-jdk_8.58.0.13-8.0.312-win_x64.msi', 'C:\%PACKAGE%') RUN msiexec /quiet /i C:\%PACKAGE% RUN del C:\%PACKAGE% RUN setx PACKAGE zulu-8-azure-jre_8.58.0.13-8.0.312-win_x64.msi RUN setx PACKAGE_DIR zulu-8/8u312 RUN setx /m JAVA_HOME "C:\temp\zulu-8-jre" RUN setx /m JAVA_HOME "C:\temp\zulu-8-jre\bin" RUN powershell -Command [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12;(new-object System.Net.WebClient).DownloadFile('https://repos.azul.com/azure-only/zulu/packages/zulu-8/8u312/zulu-8-azure-jre_8.58.0.13-8.0.312-win_x64.msi', 'C:\%PACKAGE%') RUN msiexec /quiet /i C:\%PACKAGE% RUN del C:\%PACKAGE% RUN powershell -Command $ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue'; [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; Invoke-WebRequest -UseBasicParsing -Uri https://dot.net/v1/dotnet-install.ps1 -OutFile dotnet-install.ps1; ./dotnet-install.ps1 -InstallDir '/Program Files/dotnet' -Channel 6.0 -Runtime dotnet; RUN Remove-Item -Force dotnet-install.ps1 #RUN setx /M PATH "%PATH%;C:\dotnet"
ASP.NET Core应用镜像Dockerfile
FROM mcr.microsoft.com/dotnet/sdk:6.0 as build-env WORKDIR /Program Files/dotnet COPY *.csproj ./ RUN dotnet restore COPY . ./ RUN dotnet publish -c Release -o out FROM newbaseimage:5.0 as runtime #FROM mcr.microsoft.com/dotnet/aspnet:6.0 as runtime #FROM newbaseimage:5.0 as installer WORKDIR /Program Files/dotnet COPY --from=build-env /app/out . #COPY VC_redist.x64.exe . #RUN VC_redist.x64.exe /install /passive /norestart /log out.txt EXPOSE 80 ENTRYPOINT ["dotnet", "TestDesignStudioAPI.dll"] #Environment variables to connect to Azure ENV AZURE_CLIENT_ID=6baec3cf-e284-4db8-8576-5af4320f3849 \ AZURE_CLIENT_SECRET=LOm8Q~UM7fQDLFSsuvgnzv9wsTE2zFtsQAa4WbjQ \ AZURE_TENANT_ID=0fe67bdb-a749-4082-a35f-fa9f9579a348
核心问题分析
错误提示“系统找不到指定文件”,大概率是以下几个原因:
dotnet命令不在容器的PATH环境变量中,导致无法找到- 发布的
TestDesignStudioAPI.dll路径错误,容器找不到该文件 - 基础镜像中.NET Runtime安装不完整或路径配置错误
具体修复步骤
修正基础镜像的PATH配置
基础镜像中安装.NET Runtime到了C:\Program Files\dotnet,但最后一行的PATH配置被注释掉了,需要取消注释并修正路径:RUN setx /M PATH "%PATH%;C:\Program Files\dotnet"确保容器启动时能找到
dotnet命令。修正应用镜像的文件复制路径
构建阶段build-env的WORKDIR是/Program Files/dotnet,执行dotnet publish后,发布文件会在/Program Files/dotnet/out目录下,但应用镜像中用了错误的/app/out路径,应该改成:COPY --from=build-env "/Program Files/dotnet/out" .验证DLL文件是否存在
可以临时修改应用镜像的ENTRYPOINT,进入容器查看文件位置:ENTRYPOINT ["cmd"]运行容器后执行
dir,确认当前目录存在TestDesignStudioAPI.dll后,再改回原ENTRYPOINT。检查基础镜像中.NET Runtime的安装
在基础镜像中添加验证步骤,确保dotnet安装成功:RUN dotnet --version如果安装失败,检查
dotnet-install.ps1的执行日志,确认Runtime是否正确下载并安装到指定目录。统一Windows容器路径格式
Windows容器中尽量使用反斜杠路径,避免混用正斜杠导致路径解析错误,比如将/Program Files/dotnet改为C:\Program Files\dotnet。
内容的提问来源于stack exchange,提问作者Vijayarajan Venkateswaran

