Docker .NET 4.7.2镜像无法安装NuGet包提供器求助
自2024年3月初起,拉取最新mcr.microsoft.com/dotnet/framework/runtime:4.7.2镜像后,原Dockerfile中安装SqlServer模块的命令执行失败。
原Dockerfile代码:
FROM mcr.microsoft.com/dotnet/framework/runtime:4.7.2 # 安装SqlServer模块 RUN powershell -Command \ [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; \ Install-PackageProvider -Name NuGet -Force; \ Install-Module -Name SqlServer -Force -AllowClobber;
执行时抛出异常:
Install-PackageProvider : No match was found for the specified search criteria for the provider 'NuGet'. The package provider requires 'PackageManagement' and 'Provider' tags. Please check if the specified package has the tags.
已尝试但无效的方案:
- 通过二进制方式设置TLS为1.2
- 设置执行策略为Bypass
- 为32位和64位.NET Framework启用强加密
- 尝试通过PowerShellGet安装NuGet
- 尝试直接使用URL注册Package-Source源
- 尝试拉取不同标签的镜像
- 拆分命令,在安装NuGet前重启PowerShell
- 下载nuget.exe,绕过证书验证并设置别名,但Install-Module未使用该别名
当前用于分析的Dockerfile:
FROM mcr.microsoft.com/dotnet/framework/runtime:4.7.2-20240213-windowsservercore-ltsc2019 # 安装SqlServer模块 RUN powershell -Command \ Set-ExecutionPolicy Bypass -Scope Process -Force; \ [System.Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; \ [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; \ [System.Net.ServicePointManager]::SecurityProtocol; \ # 为64位.NET Framework(4及以上版本)设置强加密 Set-ItemProperty -Path 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord; \ # 为32位.NET Framework(4及以上版本)设置强加密 Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord; #[Net.ServicePointManager]::SecurityProtocol; #Get-Module PowerShellGet, PackageManagement -ListAvailable; \ #$PSVersionTable.PSVersion; \ RUN powershell -Command exit; RUN powershell -Command \ class TrustAllCertsPolicy : System.Net.ICertificatePolicy { [bool] CheckValidationResult([System.Net.ServicePoint] $a, [System.Security.Cryptography.X509Certificates.X509Certificate] $b, [System.Net.WebRequest] $c, [int] $d) { return $true }}; \ [System.Net.ServicePointManager]::CertificatePolicy = [TrustAllCertsPolicy]::new(); \ Invoke-WebRequest "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe" -OutFile "C:\nuget.exe"; \ Set-Alias nuget "C:\nuget.exe" -Scope Global -Verbose; \ #Install-Module PowerShellGet -Force -AllowClobber; \ #Install-PackageProvider -Name NuGet -Force; \ #Install-PackageProvider -Name 'NuGet' -Source 'PSGallery' -Scope 'CurrentUser' -Verbose -Force; \ #Register-PackageSource -Name "NuGet" -Location "https://api.nuget.org/v3/index.json" -ProviderName NuGet -Force; \ Install-Module -Name SqlServer -Force -AllowClobber -Verbose;
补充:镜像中的PowerShell版本为5.1。
求问:问题根源是什么?还有哪些可尝试的解决方案?欢迎提供任何实用建议。
可尝试的解决方案建议
指定NuGet包源的具体版本
尝试安装特定版本的NuGet包提供程序,旧版本可能兼容性更好:Install-PackageProvider -Name NuGet -RequiredVersion 2.8.5.201 -Force手动更新PackageManagement和PowerShellGet模块
先卸载旧版本,再手动下载模块包传入容器安装:# 提前将模块包放入构建上下文的modules目录 COPY modules/ C:\temp\modules\ RUN powershell -Command \ Uninstall-Module -Name PackageManagement -Force -AllVersions; \ Uninstall-Module -Name PowerShellGet -Force -AllVersions; \ Install-Module -Path C:\temp\modules\PackageManagement.1.4.8.nupkg -Force; \ Install-Module -Path C:\temp\modules\PowerShellGet.2.2.5.nupkg -Force使用SqlServer模块离线包
预先在本地下载SqlServer模块的离线包,复制到容器内直接安装:COPY SqlServerOffline/ C:\SqlServerOffline\ RUN powershell -Command Install-Module -Path C:\SqlServerOffline\ -Force -AllowClobber检查PSGallery源可用性
在容器内执行命令确认源是否可访问:Get-PackageSource Test-Connection -ComputerName api.nuget.org -Port 443切换到完整Windows Server Core镜像
尝试使用包含更多组件的windowsservercore全量镜像,而非runtime基础镜像,可能自带更完善的包管理组件。
内容的提问来源于stack exchange,提问作者lekxy

