Docker构建时dotnet publish遇NuGet SSL连接错误,本地运行正常
我之前碰到过完全一样的问题,和你怀疑的一样,就是代理环境搞的鬼——Docker容器默认不会继承宿主的代理配置,所以在构建过程中访问NuGet源时就会出现SSL连接错误。
先把你的问题场景整理出来:
我的Dockerfile内容:
FROM microsoft/aspnetcore-build:2.0 AS build-env WORKDIR /app # Copy csproj and restore as distinct layers COPY *.sln ./ RUN dotnet restore # Copy everything else and build COPY . ./ RUN dotnet publish -c Release -o out # Build runtime image FROM microsoft/aspnetcore:2.0 WORKDIR /app COPY --from=build-env /app/out . ENTRYPOINT ["dotnet", "salesorder.qry.webapiapp.dll"]
Docker构建时的错误日志:
$ docker build -t salesorder.qry.webapiapp . Sending build context to Docker daemon 126.1MB Step 1/10 : FROM microsoft/aspnetcore-build:2.0 AS build-env ---> 07590dec9c1e Step 2/10 : WORKDIR /app ---> Using cache ---> 26007abaa8b5 Step 3/10 : COPY *.sln ./ ---> Using cache ---> 69dc09df88f0 Step 4/10 : RUN dotnet restore ---> Using cache ---> 7c10e448f636 Step 5/10 : COPY . ./ ---> Using cache ---> c588d98eb49b Step 6/10 : RUN dotnet publish -c Release -o out ---> Running in 9492a4f61e38 Microsoft (R) Build Engine version 15.7.177.53362 for .NET Core Copyright (C) Microsoft Corporation. All rights reserved. Restoring packages for /app/SalesOrder.Cmd.Application.Model.Events/SalesOrder.Cmd.Application.Model.Events.csproj... Restoring packages for /app/SalesOrder.Cmd.Application.Model/SalesOrder.Cmd.Application.Model.csproj... /usr/share/dotnet/sdk/2.1.200/NuGet.targets(114,5): error : Unable to load the service index for source https://api.nuget.org/v3/index.json. [/app/SalesOrder.Qry.sln] /usr/share/dotnet/sdk/2.1.200/NuGet.targets(114,5): error : An error occurred while sending the request. [/app/SalesOrder.Qry.sln] /usr/share/dotnet/sdk/2.1.200/NuGet.targets(114,5): error : SSL connect error [/app/SalesOrder.Qry.sln] The command '/bin/sh -c dotnet publish -c Release -o out' returned a non-zero code: 1
本地直接执行dotnet publish却正常:
$ dotnet publish -c Release -o out Microsoft (R) Build Engine version 15.6.84.34536 for .NET Core Copyright (C) Microsoft Corporation. All rights reserved. Restore completed in 43,43 ms for C:\src\SalesOrder.QueryService\SalesOrder.Cmd.Application.Model\SalesOrder.Cmd.Application.Model.csproj. Restore completed in 43,43 ms for C:\src\SalesOrder.QueryService\SalesOrder.Cmd.Application.Model.Events\SalesOrder.Cmd.Application.Model.Events.csproj. Restore completed in 4,67 ms for C:\src\SalesOrder.QueryService\SalesOrder.Qry.Infra.InMemoryRepository\SalesOrder.Qry.Infra.InMemoryRepository.csproj. Restore completed in 46,18 ms for C:\src\SalesOrder.QueryService\SalesOrder.Qry.Application.UnitTests\SalesOrder.Qry.Application.UnitTests.csproj. Restore completed in 51,08 ms for C:\src\SalesOrder.QueryService\SalesOrder.Qry.WebApi.UnitTests\SalesOrder.Qry.WebApi.UnitTests.csproj. Restore completed in 32,46 ms for C:\src\SalesOrder.QueryService\SalesOrder.Qry.WebApiApp\SalesOrder.Qry.WebApiApp.csproj. Restore completed in 12,53 ms for C:\src\SalesOrder.QueryService\ToolBelt.Hateoas\ToolBelt.Hateoas.csproj. Restore completed in 13,54 ms for C:\src\SalesOrder.QueryService\SalesOrder.Qry.WebApi\SalesOrder.Qry.WebApi.csproj. Restore completed in 2,16 ms for C:\src\SalesOrder.QueryService\ToolBelt.Mapping.Contracts\ToolBelt.Mapping.Contracts.csproj. Restore completed in 1,97 ms for C:\src\SalesOrder.QueryService\ToolBelt.Tests.Extensions\ToolBelt.Tests.Extensions.csproj. Restore completed in 55,52 ms for C:\src\SalesOrder.QueryService\SalesOrder.Qry.WebApiApp\SalesOrder.Qry.WebApiApp.csproj. Restore completed in 64,69 ms for C:\src\SalesOrder.QueryService\SalesOrder.Qry.Application.UnitTests\SalesOrder.Qry.Application.UnitTests.csproj. Restore completed in 2,36 ms for C:\src\SalesOrder.QueryService\SalesOrder.Qry.Domain.EventContracts\SalesOrder.Qry.Domain.EventContracts.csproj. Restore completed in 2,87 ms for C:\src\SalesOrder.QueryService\SalesOrder.Qry.Application\SalesOrder.Qry.Application.csproj. SalesOrder.Cmd.Application.Model -> C:\src\SalesOrder.QueryService\SalesOrder.Cmd.Application.Model\bin\Release\netstandard2.0\SalesOrder.Cmd.Application.Model.dll ToolBelt.Tests.Extensions -> C:\src\SalesOrder.QueryService\ToolBelt.Tests.Extensions\bin\Release\netstandard2.0\ToolBelt.Tests.Extensions.dll ToolBelt.Mapping.Contracts -> C:\src\SalesOrder.QueryService\ToolBelt.Mapping.Contracts\bin\Release\netstandard2.0\ToolBelt.Mapping.Contracts.dll ToolBelt.Tests.Extensions -> C:\src\SalesOrder.QueryService\ToolBelt.Tests.Extensions\out\ ToolBelt.Mapping.Contracts -> C:\src\SalesOrder.QueryService\ToolBelt.Mapping.Contracts\out\ SalesOrder.Cmd.Application.Model -> C:\src\SalesOrder.QueryService\SalesOrder.Cmd.Application.Model\out\ ToolBelt.Hateoas -> C:\src\SalesOrder.QueryService\ToolBelt.Hateoas\bin\Release\netstandard2.0\ToolBelt.Hateoas.dll SalesOrder.Cmd.Application.Model.Events -> ...
解决办法
1. 用构建参数传递代理配置(推荐,灵活可控)
Docker容器不会自动使用宿主的代理,我们可以通过--build-arg把代理地址传给构建过程,再在Dockerfile里设置环境变量供dotnet和NuGet使用。
修改后的Dockerfile:
# 定义构建参数,默认空值 ARG HTTP_PROXY="" ARG HTTPS_PROXY="" ARG NO_PROXY="" FROM microsoft/aspnetcore-build:2.0 AS build-env # 把代理参数传递到build-env阶段 ARG HTTP_PROXY ARG HTTPS_PROXY ARG NO_PROXY # 设置环境变量,让dotnet识别代理 ENV HTTP_PROXY=${HTTP_PROXY} ENV HTTPS_PROXY=${HTTPS_PROXY} ENV NO_PROXY=${NO_PROXY} WORKDIR /app COPY *.sln ./ RUN dotnet restore COPY . ./ RUN dotnet publish -c Release -o out FROM microsoft/aspnetcore:2.0 WORKDIR /app COPY --from=build-env /app/out . ENTRYPOINT ["dotnet", "salesorder.qry.webapiapp.dll"]
然后执行构建命令时,传入你的代理信息:
docker build -t salesorder.qry.webapiapp \ --build-arg HTTP_PROXY=http://your-proxy-address:port \ --build-arg HTTPS_PROXY=http://your-proxy-address:port \ --build-arg NO_PROXY=localhost,127.0.0.1,.your-internal-domain \ .
2. 直接在Dockerfile中硬编码代理(不推荐,不够灵活)
如果你的代理地址长期固定,可以直接在build-env阶段添加环境变量:
FROM microsoft/aspnetcore-build:2.0 AS build-env ENV HTTP_PROXY=http://your-proxy-address:port ENV HTTPS_PROXY=http://your-proxy-address:port ENV NO_PROXY=localhost,127.0.0.1 WORKDIR /app # 后续步骤不变
3. 处理自签名代理证书问题
如果你的代理使用了自签名SSL证书,还需要把证书导入到容器的信任存储中,否则会出现SSL验证失败。对于基于Debian的aspnetcore-build镜像,可以这样做:
FROM microsoft/aspnetcore-build:2.0 AS build-env # 把代理证书复制到容器内 COPY your-proxy-cert.crt /usr/local/share/ca-certificates/ # 更新系统证书存储 RUN update-ca-certificates # 再设置代理环境变量...
内容的提问来源于stack exchange,提问作者diegosasw
相关产品推荐
相关产品推荐

