1

I have Artifacts in Azure DevOps and trying to create a docker build.

  • Platform: Microsoft .NET Core 3.1
  • Docker (local): 19.03.12

Steps I did:

  1. Created a PAT in Azure DevOps (with full permissions)
  2. Generated a Dockerfile using Visual Studio 2019
  3. Added it in Dockerfile:

ENV VSS_NUGET_EXTERNAL_FEED_ENDPOINTS
"{"endpointCredentials": [{"endpoint":"https://pkgs.dev.azure.com/MYCOMPANY/_packaging/MYPROJECT/nuget/v3/index.json", "username":"USER", "password":"GENERATED_PAT"}]}"

  1. After COPY commands added:

RUN dotnet restore -s "https://https://pkgs.dev.azure.com/MYCOMPANY/_packaging/MYPROJECT/nuget/v3/index.json" "Project/ProjectName.csproj"

But I receive an "unauthorized" error when I run: docker build . -t mydockerfile:v1

/usr/share/dotnet/sdk/3.1.401/NuGet.targets(128,5): error : Unable to load the service index for source https://pkgs.dev.azure.com/MYCOMPANY/_packaging/MYPROJECT/nuget/v3/index.json. [/src/Project/ProjectName.csproj] /usr/share/dotnet/sdk/3.1.401/NuGet.targets(128,5): error : Response status code does not indicate success: 401 (Unauthorized). [/src/Project/ProjectName.csproj] The command '/bin/sh -c dotnet restore -s "https://pkgs.dev.azure.com/MYCOMPANY/_packaging/MYPROJECT/nuget/v3/index.json" "Project/ProjectName.csproj"' returned a non-zero code: 1

Dockerfile

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
WORKDIR /app
EXPOSE 80

ENV NUGET_CREDENTIALPROVIDER_SESSIONTOKENCACHE_ENABLED true
ENV VSS_NUGET_EXTERNAL_FEED_ENDPOINTS \
"{"endpointCredentials": [{"endpoint":"https://pkgs.dev.azure.com/MYCOMPANY/_packaging/MYPROJECT/nuget/v3/index.json", "username":"USER", "password":"GENERATED_PAT"}]}"


FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src

COPY ["MyAPP.Api/MyAPP.Api.csproj", "MyAPP.Api/"]
COPY ["MyAPP.DI/MyAPP.DI.csproj", "MyAPP.DI/"]
COPY ["MyAPP.Application/MyAPP.Application.csproj", "MyAPP.Application/"]
COPY ["MyAPP.Domain/MyAPP.Domain.csproj", "MyAPP.Domain/"]
COPY ["MyAPP.Infrastructure/MyAPP.Infrastructure.csproj", "MyAPP.Infrastructure/"]

RUN dotnet restore -s "https://pkgs.dev.azure.com/MYCOMPANY/_packaging/MYPROJECT/nuget/v3/index.json" "MyAPP.Domain/MyAPP.Domain.csproj"

COPY . .
WORKDIR "/MyAPP.Api"
RUN dotnet build "MyAPP.Api.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "MyAPP.Api.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "MyAPP.Api.dll"]
Dimitri
  • 141
  • 2
  • 4
  • 18
  • Any update for this issue? The `endpointCredentials` way won't work if you doesn't have `Azure Artifacts Credential Provider ` installed. Maybe you can use nuget.config way for your authentication, check my another ticker [here](https://stackoverflow.com/a/61726823/10910450). Also this [similar one](https://stackoverflow.com/a/39875460/10910450). – LoLance Sep 08 '20 at 09:33
  • Hi, is there any update for this issue? Please check if my answer below resolves your issue and feel free to let me know if you're blocked. In addition, here's [one blog](https://huorswords.github.io/azure/pipeline/devops/docker/artifacts/nuget/2019/10/28/access-private-azure-artifacts-from-docker.html) which can help for you, it contains one dockerfile with steps to set the ENV and install the Artifact Credential provider. – LoLance Sep 15 '20 at 09:32

2 Answers2

0

Main cause of the issue:

The dotnet restore command can't actually access the credentials you set via ENV.

You can add RUN printenv to print the ENV variables.

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
WORKDIR /app
EXPOSE 80

ENV NUGET_CREDENTIALPROVIDER_SESSIONTOKENCACHE_ENABLED true
ENV VSS_NUGET_EXTERNAL_FEED_ENDPOINTS \
"{"endpointCredentials": [{"endpoint":"https://pkgs.dev.azure.com/MYCOMPANY/_packaging/MYPROJECT/nuget/v3/index.json", "username":"USER", "password":"GENERATED_PAT"}]}"
RUN printenv

FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
RUN printenv

enter image description here

enter image description here

Check the log of first printenv and second printenv command and you can find the environment you run the dotnet restore can't access the credentials.

Solution:

You can move/copy the define ENV step just before the RUN dotnet restore step.

FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src

...

ENV NUGET_CREDENTIALPROVIDER_SESSIONTOKENCACHE_ENABLED true
ENV VSS_NUGET_EXTERNAL_FEED_ENDPOINTS \
"{"endpointCredentials": [{"endpoint":"https://pkgs.dev.azure.com/MYCOMPANY/_packaging/MYPROJECT/nuget/v3/index.json", "username":"USER", "password":"GENERATED_PAT"}]}"

RUN dotnet restore -s "https://pkgs.dev.azure.com/MYCOMPANY/_packaging/MYPROJECT/nuget/v3/index.json" "MyAPP.Domain/MyAPP.Domain.csproj"
LoLance
  • 25,666
  • 1
  • 39
  • 73
  • @Dimitri What's the result if you set the ENV and then run the same dotnet restore command locally? Does it work? – LoLance Sep 02 '20 at 09:46
  • @Dimitri Does the nuget feed exist in the same team project in which you run the pipeline? – LoLance Sep 02 '20 at 09:56
  • No, they are different projects. Also, the project with Artifacts is set to public and the PAT is generated from the Admin user – Dimitri Sep 02 '20 at 11:24
  • "What's the result if you set the ENV and then run the same dotnet restore command locally? Does it work?" Did not get exactly. How to do this? – Dimitri Sep 02 '20 at 13:30
  • @Dimitri I'll try to reproduce the issue with latest info above and let you know. About ` what ... locally`, I mean you can [set the ENV](https://github.com/Microsoft/artifacts-credprovider/blob/master/README.md#environment-variables) in local machine, run `dotnet restore command` manually in CMD, so that we would know whether there's something wrong with your ENV step. – LoLance Sep 03 '20 at 09:52
  • @Dimitri Check [this link](https://learn.microsoft.com/en-us/azure/devops/artifacts/nuget/dotnet-exe?view=azure-devops#on-build-machines-and-in-non-interactive-scenarios) carefully. `Otherwise, use the Azure Artifacts Credential Provider and pass in credentials using the VSS_NUGET_EXTERNAL_FEED_ENDPOINTS environment variable.` Apart from the Env step's position, you also forgot to install the `Credential Provider` in your docker container. The Env won't work if the Credential Provider is not installed. – LoLance Sep 04 '20 at 10:01
0

I had the similar issue and the problem was that I was using wrong username in my nuget.config. According to your solution, the username should be MYCOMPANY.

Like so: "{"endpointCredentials": [{"endpoint":"https://pkgs.dev.azure.com/MYCOMPANY/_packaging/MYPROJECT/nuget/v3/index.json", "username":"MYCOMPANY", "password":"GENERATED_PAT"}]}"

Also, I did not need to use this. When I configured my nuget.config file like this:

<configuration>
<packageSources>
    <clear />
    <add key="MYCOMPANYNAME" value="https://pkgs.dev.azure.com/MYCOMPANY/_packaging/MYPROJECT/nuget/v3/index.json" />
    <add key="NuGet" value="https://api.nuget.org/v3/index.json" />
</packageSources>
<packageSourceCredentials>
    <Spordrift>
        <add key="Username" value="MYCOMPANY" />
        <add key="ClearTextPassword" value="GENERATED PAT*" />
    </Spordrift>
</packageSourceCredentials>
</configuration>

and my Dockerfile like this (notice that I copied nuget.config file as well):

FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
COPY ["nuget.config", "./"]
COPY ["MyAPP.Api.csproj", "MyAPP/"]

RUN dotnet restore "MyAPP.Api.csproj"

COPY . .
WORKDIR "/MyAPP.Api"
RUN dotnet build "MyAPP.Api.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "MyAPP.Api.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "MyAPP.Api.dll"]

everything worked as expected. I did not need to pollute my Dockerfile with a lot of configurations. nuget.config was enough to put everything in.

Serhat
  • 216
  • 2
  • 17