【问题标题】:Dockerfile can't see local file or private nuget serverDockerfile 看不到本地文件或私有 nuget 服务器
【发布时间】:2018-07-27 01:56:02
【问题描述】:

我正在尝试在容器技术上启动我的 .net 核心 Web api。使用 docker。

环境=Windows 10、Visual Studio

Docker 版本:

客户:

版本:17.12.0-ce

API 版本:1.35

Go 版本:go1.9.2

Git 提交:c97c6d6

建成时间:2017 年 12 月 27 日星期三 20:05:22

操作系统/Arch:windows/amd64

服务器:

引擎:

版本:17.12.0-ce

API 版本:1.35(最低版本 1.12)

Go 版本:go1.9.2

Git 提交:c97c6d6

建成时间:2017 年 12 月 27 日星期三 20:12:29

操作系统/Arch:linux/amd64

实验性:真实

我的 Nuget.Config 文件:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>


<add key="nuget.org" value="https://api.nuget.org/v3/index.json" 
protocolVersion="3" />


<add key="Private" 
value="http://My_Private_Nuget_Server" />


</packageSources>
<packageRestore>
<add key="enabled" value="True" />
<add key="automatic" value="True" />
</packageRestore>
<bindingRedirects>
<add key="skip" value="False" />
</bindingRedirects>
<packageManagement>
<add key="format" value="0" />
<add key="disabled" value="True" />
</packageManagement>


<apikeys>
<add key="https://www.nuget.org" value="Some_Long_Value" />
</apikeys>


<disabledPackageSources />
</configuration>

我的 Dockerfile:

FROM microsoft/aspnetcore-build:2.0 AS build-env
WORKDIR /app

# Copy csproj and restore as distinct layers
COPY *.csproj ./
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", "MailAlertWebApiWithEF.dll"]

我在 Windows 10 机器上使用 Linux Container。我在 Visual Studio 17 上有 .net 核心项目。当我添加 docker 支持并从 VS 17 运行时,一切正常。 API在容器内站立。但是当我关闭VS时不起作用。但是,当我尝试自定义我的 dockerfile 以使我的图像和容器独立于 VS 时。由于私有.dll,它会给出错误。

在我的项目中,我有一个来自我的私人 nuget 服务器的 .dll。当我在没有我的私人.dll 的情况下尝试时,我可以创建图像。但我需要.dll。 Docker 给我这个错误:

MailAlertWebApiWithEF.csproj:错误 NU1101:无法找到包 WebApi.Utils。源中不存在具有此 ID 的软件包: nuget.org

我搜索了这个错误。问题的根源似乎是 Nuget.Config 文件。但这对我来说似乎很好,因为我可以在那里看到我的私人 nuget 服务器。当我总是在 linux 机器上搜索解决方案箭头但我使用 windows。

1-)因此,如果我可以使用 VS 17 启动我的项目,那么我的 nuget.config 文件格式正确。它可以看到我的私人 nuget 服务器。正确的?那为什么 docker 看不到呢?

请帮忙

【问题讨论】:

  • 我找到了问题但没有解决。 “Dotnet Restore”命令不安装我的私人包之一,而是从我的私人服务器安装其他包。
  • Dotnet Restore' command don't install one of my private package 那个包是 .NET Framework 库吗?如果是,命令行 dotnet restore 无法解析 .NET Framework 库,可以尝试使用nuget restoregithub.com/dotnet/cli/issues/3199
  • 都是 .net 标准库和兼容 .net 核心。

标签: c# visual-studio docker nuget


【解决方案1】:

对于那些使用私有存储库自定义 nuget 提要运行 dotnet restore的用户> 是失败,那么你可以这样做:

尤其适用于:您的 NuGet.Config 包含私有 repo 端点和凭据,然后

  1. 将系统的 NuGet.Config 复制到 .csproject 所在的同一根级别的项目文件夹中。

  2. 现在在 docker 文件中将这些语句放在您尝试恢复包之前:

    COPY ./NuGet.Config ./

  3. 之后,在 dotnet restore 命令中追加配置文件位置,如下所示:

    RUN dotnet restore &lt;CS_project_name&gt;.csproj --configfile ./NuGet.Config

  4. 现在做剩下的你想做的事情。

  5. 就在入口点之前的末尾或复制到其他容器之前(在多阶段构建的情况下),删除 NuGet.Config 是个好主意,因为我们不希望这样可以在 pod/container 中查看

RUN rm ./NuGet.Config

[更新]就像https://github.com/NuGet/Home/issues/4413#issuecomment-483920015

中提到的

如果我们使用下面的复制命令把它放到文件系统的根目录下

COPY ./NuGet.Config /nuget.config

那么我们在dotnet restore期间不需要指定配置文件的位置

【讨论】:

  • 值得注意的是,RUN rm ./NuGet.Config 不能在 Windows 上工作,您需要使用 RUN del -f "./NuGet.Config"
  • @devnsyde ,基本上我们正在尝试从构建容器中删除这个 nuget।config ,这样即使有人下载并执行内部映像,他也不应该知道私人回购的凭据,因此 rm 命令实际上在 Linux 容器操作系统中运行并且运行良好,没有任何问题,我们不会从 Windows 中删除任何内容
  • 我知道答案是针对运行 linux 的人,但是当我试图弄清楚为什么 RM 在我的 docker 文件中不起作用时,我登陆了这个页面,这是因为我在 Windows 容器上.现在,当来自 Windows 的人登陆这个答案时,他们可以看到改用 DEL
  • 这个答案极大地帮助了我,这要感谢将配置文件位置附加到 dotnet restore 命令的说明。我不知道这是必要的:)
  • 对此的扩展,来自 0909EM 和此处 github.com/NuGet/Home/issues/4413#issuecomment-483920015 的此答案 stackoverflow.com/a/63938470 也有助于通过将文件放置在以下位置:/root/.nuget/NuGet/NuGet.Config/nuget.config docker 默认会看到它.
【解决方案2】:

为了让在容器内运行的 dotnet 命令找到您的自定义提要,还必须将 nuget.config 文件复制到容器中。

为此,请将带有您的私人提要的nuget.config 文件添加到您的项目文件夹中,并添加一个额外的COPY 步骤,将该文件复制到容器中。

示例(Dockerfile):

WORKDIR ...
COPY NuGet.Config /
COPY ... ...

【讨论】:

  • COPY NuGet.Config / 这对我的失败,即使文件在那里
  • 对于那些已将 Visual Studio 配置为使用 PackageReference 格式(其中包在机器级别缓存)的用户,nuget.config 文件可能位于 $HOME\AppData\Roaming\NuGet 中(作为 Windows 路径)
  • 我刚刚发现 nuget.config(文件名)在 Linux 上是区分大小写的,这并不令人惊讶,但我发现了!
【解决方案3】:

您可以通过 dotnet 命令添加私有 nuget,无需链接到 nuget.config 文件。

COPY *.csproj ./  

RUN dotnet nuget add source <source-value-of-nuget> -n <name> 

RUN dotnet restore 

【讨论】:

  • 由于某种奇怪的原因,无论我如何解决,docker 都找不到我的 nuget.config 文件,但您的解决方案效果很好,感谢您在花了 2 小时解决后节省了我的时间..
  • 我遇到了同样的问题,即我的副本无法正常工作。 Was = " COPY nuget.config ." / IS = " COPY /Source/nuget.config ." 我的解决方案位于根目录中,而我的项目 + nuget.config 文件位于子文件夹“Source”中
【解决方案4】:

在寻找另一个 nuget 问题/答案时偶然发现了这个......

要从 docker 中恢复,如 this answer 中所述,首先将 nuget.config 文件复制到容器中,我建议您将其放置在 /root/.nuget/NuGet 文件夹中并使用多级 Dockerfile,这样,您不需要无需担心删除它。

如果有帮助,这就是我的设置...

--nuget.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <add key="PrivateFeed" value="https://private.nuget.feed.net/" />
  </packageSources>
  <packageSourceCredentials>
    <PrivateFeed>
      <add key="Username" value="username" />
      <add key="ClearTextPassword" value="plaintext_password" />
    </PrivateFeed>
  </packageSourceCredentials>
</configuration>

多阶段 Dockerfile...

FROM mcr.microsoft.com/dotnet/core/sdk:3.1.201 as sdk-build
WORKDIR /app

# Skip extraction of XML documentation for nuget packages
ENV NUGET_XMLDOC_MODE=skip

# We'll copy the nuget config file to the right place
# which should mean it doesn't get copied to our deployed containers
# and we can just call 'dotnet restore' with specifying a config file
COPY ./Nuget.Config /root/.nuget/NuGet/NuGet.Config

# Make use of cached layers, by only doing a restore when the config changes
COPY ./*.sln ./**/*.csproj ./

# Then within a RUN command to copy them to the right folders.
RUN for file in $(ls *.csproj); do mkdir -p ${file%.*}/ && mv $file ${file%.*}/; done \
    && dotnet restore

# Copy the source code
COPY . .

# Now do a build/publish here
RUN dotnet publish "./project/project.csproj" --output /app/output


FROM mcr.microsoft.com/dotnet/core/aspnet:3.1.2
WORKDIR /app
COPY --from=sdk-build /app/output ./
ENTRYPOINT ["./project"]

【讨论】:

    【解决方案5】:

    如果您的“私人 nuget 提要”可通过 url 访问,则将 Nuget.Config 复制到解决方案或项目文件夹将起作用。 但是,如果私有提要是用作 nuget 源的本地文件夹,则此方法仍然会失败,并显示该文件夹在构建上下文之外的错误,或者仅仅是因为 Docker 构建过程没有解析 Windows 路径。

    例如如果你Nuget.Config 有这样的东西:

      <packageSources>
        <add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
        <add key="My Local" value="C:\dev\nuget-packages" />
      </packageSources>
    
    

    Docker 上下文将无法解析 C:\dev\nuget-packages

    放弃在 docker 内构建并预先发布已编译的解决方案并从中构建映像是很诱人的......

    但另一种解决方法(需要更多步骤)也是可能的: 运行dotnet restore 之前 运行docker-compose 命令,并使用--packages 选项将恢复的包保存到解决方案文件夹 例如

    dotnet-restore C:\slnfolder\myproj\myapp.csproj --packages C:\slnfolder\packages

    (这可以与 docker-compose 命令一起包含在单个 powershell 脚本中。)

    然后在 Dockerfile(docker-compose 用于构建映像)中,假设上下文是解决方案文件夹,WORKDIR'/src'

    COPY packages/. packages/.

    并将 Dockerfile 恢复行修改为

    RUN dotnet restore "myproj/myapp.csproj" -s /src/packages -s https://api.nuget.org/v3/index.json

    【讨论】:

      【解决方案6】:

      这个问题不需要复杂的解决方案。 为了让您的“dotnet publish”正常工作,它需要知道在哪里查找 NuGet 包,并且 NuGet 包应该在该位置可用。

      因此您只需将包含 NuGet 包的文件夹复制到容器中,然后使用以下命令告诉构建实用程序在哪里查找

      RUN dotnet nuget add source /repo/nuget-local-source -n local-repo
      

      【讨论】:

        猜你喜欢
        • 2020-08-08
        • 1970-01-01
        • 2022-07-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-07-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多