skip to Main Content

I have a yaml Azure DevOps pipeline as below which is trying to consume a nuget feed from another organization.

As you can see I am using the nugetauthenticate@1 task to create valid credentials using a Service Connection created by a user in the target organization.

I have a docker file called by the pipeline in which I install the artifacts credential provider via their sh script.

I am setting the JSON environment variable in the dockerfile with a valid PAT passed into the docker task:

arguments: '--build-arg FEED_ACCESSTOKEN=$(VSS_NUGET_ACCESSTOKEN)'

n.b. I have tried using the cred provider variable $(VSS_NUGET_ACCESSTOKEN) and by using my own pipeline variable containing a valid PAT.

When I call dotnet restore in the docker step the step faults with:

error NU1301: Unable to load the service index for source https://pkgs.dev.azure.com/{org}/_packaging/{feed}/nuget/v3/index.json

I’ve turned on verbose logging and the credential provider is using the provided configuration but I don’t get an Auth (401) issue, just an error hitting the nuget index page feed so i think its not even getting a chance to authenticate.

Any advice would be greatly appreciated.

Pipeline:

trigger:
- main

pool:
  vmImage: 'ubuntu-latest'

variables:  
  buildConfiguration: 'Release'
  NUGET.PLUGIN.HANDSHAKE.TIMEOUT.IN.SECONDS: 20
  NUGET.PLUGIN.REQUEST.TIMEOUT.IN.SECONDS: 20

steps:

- task: NuGetAuthenticate@1
  inputs:
    nuGetServiceConnections: 'nuget-feed'

- task: NodeTool@0
  inputs:
    versionSpec: '18.17.1'

- task: DotNetCoreCLI@2
  inputs:
    command: 'build'
    arguments: 'xxx/xxx.sln'

- task: Docker@2
  inputs:
    command: 'build'
    Dockerfile: 'xxx/xxx/Dockerfile'
    buildContext: 'xxx'
    arguments: '--build-arg FEED_ACCESSTOKEN=$(VSS_NUGET_ACCESSTOKEN)'
    
- task: PublishBuildArtifacts@1
  inputs:
    PathtoPublish: '$(Build.ArtifactStagingDirectory)'
    ArtifactName: 'drop'
    publishLocation: 'Container'

Docker file:

FROM mcr.microsoft.com/dotnet/aspnet:6.0.14-bullseye-slim-amd64 AS base
ARG FEED_ACCESSTOKEN

WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:6.0.427-1-bullseye-slim-amd64 AS build

ENV NUGET_PLUGIN_HANDSHAKE_TIMEOUT_IN_SECONDS=60
ENV NUGET_PLUGIN_REQUEST_TIMEOUT_IN_SECONDS=60
RUN curl -L https://raw.githubusercontent.com/Microsoft/artifacts-credprovider/master/helpers/installcredprovider.sh  | sh

WORKDIR /src
COPY ["xxx/xxx.csproj", "xxx/"]
COPY ["xxx/nuget.config", "xxx/"]

ENV VSS_NUGET_EXTERNAL_FEED_ENDPOINTS="{"endpointCredentials": [{"endpoint":"https://pkgs.dev.azure.com/{org}/_packaging/{feed}/nuget/v3/index.json", "username":"docker", "password":"${FEED_ACCESSTOKEN}"}]}"
RUN echo $VSS_NUGET_EXTERNAL_FEED_ENDPOINTS

RUN dotnet restore "xxx/xxx.csproj" --verbosity detailed

2

Answers


  1. I can reproduce the same error using the Dockerfile you shared.

    After checking the log, I found the password is empty in the endpointCredentials command. I added the command RUN echo "Access Token: $FEED_ACCESSTOKEN" to confirm it.
    endpointCredentials

    After this, I moved the line ARG FEED_ACCESSTOKEN after FROM mcr.microsoft.com/dotnet/sdk:6.0.427-1-bullseye-slim-amd64 AS build.

    New Dockerfile:

    FROM mcr.microsoft.com/dotnet/aspnet:6.0.14-bullseye-slim-amd64 AS base
    
    WORKDIR /app
    EXPOSE 80
    EXPOSE 443
    
    FROM mcr.microsoft.com/dotnet/sdk:6.0.427-1-bullseye-slim-amd64 AS build
    ARG FEED_ACCESSTOKEN
    
    ENV NUGET_PLUGIN_HANDSHAKE_TIMEOUT_IN_SECONDS=60
    ENV NUGET_PLUGIN_REQUEST_TIMEOUT_IN_SECONDS=60
    RUN curl -L https://raw.githubusercontent.com/Microsoft/artifacts-credprovider/master/helpers/installcredprovider.sh  | sh
    
    WORKDIR /src
    COPY ["xxx/xxx.csproj", "xxx/"]
    COPY ["xxx/nuget.config", "xxx/"]
    RUN echo "Access Token: $FEED_ACCESSTOKEN"
    
    ENV VSS_NUGET_EXTERNAL_FEED_ENDPOINTS="{"endpointCredentials": [{"endpoint":"https://pkgs.dev.azure.com/{org}/_packaging/{feed}/nuget/v3/index.json", "username":"docker", "password":"${FEED_ACCESSTOKEN}"}]}"
    RUN echo $VSS_NUGET_EXTERNAL_FEED_ENDPOINTS
    
    RUN dotnet restore "xxx/xxx.csproj" --verbosity detailed
    
    

    This time, the password is not empty and the restore step is successful.

    endpointCredentials

    Cause of the issue:

    ARG variables are scoped to the stage where they are defined. So, you should move this line to the build stage where you use it.

    If you want to share variable in multi-stage Dockerfile, each stage must include the ARG instruction. You can refer this question for more information about Share variable in multi-stage Dockerfile.

    Login or Signup to reply.
  2. As shared in Miao Tian’s answer , you need to move the ARG to the correct code block in dockerfile.

    Additionally, when the Nuget Authentication task authenticates resources via service connection, its output variable: VSS_NUGET_ACCESSTOKEN is not a valid PAT/Password. Therefore, it cannot be used directly to set the environment variable: VSS_NUGET_EXTERNAL_FEED_ENDPOINTS in dockerfile.

    To solve this issue, you can directly pass PAT to dockerfile(e.g. --build-arg FEED_ACCESSTOKEN=$(YourPAT) )

    Or you can use another output variable: $(VSS_NUGET_EXTERNAL_FEED_ENDPOINTS) from Nuget Authenticate task.

    For example:

    enter image description here

    This variable is a valid feed artifacts endpoint contains password and can be directly passed to the Dockerfile for authentication.

    ARG VSS_NUGET_EXTERNAL_FEED_ENDPOINTS
    ENV VSS_NUGET_EXTERNAL_FEED_ENDPOINTS=${VSS_NUGET_EXTERNAL_FEED_ENDPOINTS} 
    

    Here is an example:

    Dockerfile:

    FROM mcr.microsoft.com/dotnet/aspnet:6.0.14-bullseye-slim-amd64 AS base
    
    WORKDIR /app
    EXPOSE 80
    EXPOSE 443
    
    FROM mcr.microsoft.com/dotnet/sdk:6.0.427-1-bullseye-slim-amd64 AS build
    
    ARG VSS_NUGET_EXTERNAL_FEED_ENDPOINTS 
    ENV NUGET_PLUGIN_HANDSHAKE_TIMEOUT_IN_SECONDS=60
    ENV NUGET_PLUGIN_REQUEST_TIMEOUT_IN_SECONDS=60
    RUN curl -L https://raw.githubusercontent.com/Microsoft/artifacts-credprovider/master/helpers/installcredprovider.sh  | sh
    
    WORKDIR /src
    COPY ["xxx/xxx.csproj", "xxx/"]
    COPY ["xxx/nuget.config", "xxx/"]
    
    ENV VSS_NUGET_EXTERNAL_FEED_ENDPOINTS=${VSS_NUGET_EXTERNAL_FEED_ENDPOINTS}
    RUN echo $VSS_NUGET_EXTERNAL_FEED_ENDPOINTS
    
    RUN dotnet restore "xxx/xxx.csproj" --verbosity detailed
    

    Since there is a known issue: [BUG]: Docker@2 arguments (VSS_NUGET_EXTERNAL_FEED_ENDPOINTS) without quotes when passing the variable:VSS_NUGET_EXTERNAL_FEED_ENDPOINTS via docker task, we need to change to use script/bash/powershell task to run docker command to build the image.

    Pipeline Sample:

    trigger:
    - main
    
    pool:
      vmImage: 'ubuntu-latest'
    
    variables:  
      buildConfiguration: 'Release'
      NUGET.PLUGIN.HANDSHAKE.TIMEOUT.IN.SECONDS: 20
      NUGET.PLUGIN.REQUEST.TIMEOUT.IN.SECONDS: 20
    
    steps:
    
    - task: NuGetAuthenticate@1
      inputs:
        nuGetServiceConnections: 'nuget-feed'
    
    - task: NodeTool@0
      inputs:
        versionSpec: '18.17.1'
    
    - task: DotNetCoreCLI@2
      inputs:
        command: 'build'
        arguments: 'xxx/xxx.sln'
    
    - script: >-
        docker build
        --build-arg VSS_NUGET_EXTERNAL_FEED_ENDPOINTS='$(VSS_NUGET_EXTERNAL_FEED_ENDPOINTS)'
        --file xxx/xxx/Dockerfile .
        
    - task: PublishBuildArtifacts@1
      inputs:
        PathtoPublish: '$(Build.ArtifactStagingDirectory)'
        ArtifactName: 'drop'
        publishLocation: 'Container'
    

    In this case, we can pass the credential from service connection to dockerfile for nuget feed authentication.

    Result:

    enter image description here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search