Search code examples
dockerasp.net-coreazure-devopsazure-artifacts

Response status code does not indicate success: 401 (Unauthorized) - Azure Devops Feed ASP.NET Core 3.1 Docker Build


I have found a few articles, and posts on this forum, relating to the issue of an Azure private artifact feeds not able to be authorized when building an image with the Docker build task in Azure, which is understandable.

So, I have put together a Dockerfile that mirrors the online examples:

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

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

EXPOSE 80

# The Personal Access Token arg
ARG NUGET_PAT

# Set environment variables
ENV NUGET_CREDENTIALPROVIDER_SESSIONTOKENCACHE_ENABLED true
ENV VSS_NUGET_EXTERNAL_FEED_ENDPOINTS '{"endpointCredentials": [{"endpoint":"https://pkgs.dev.azure.com/MY_FEED/nuget/v3/index.json", "username":"username", "password":"${NUGET_PAT}"}]}'

# install wget
RUN apt-get update && apt-get install -y wget 

# Get and install the Artifact Credential provider
RUN wget -O - https://raw.githubusercontent.com/Microsoft/artifacts-credprovider/master/helpers/installcredprovider.sh  | bash

COPY ["xxx.csproj", "."]
RUN dotnet restore -s "https://pkgs.dev.azure.com/MY_FEED/nuget/v3/index.json" -s "https://api.nuget.org/v3/index.json"

COPY . .
WORKDIR "/src"
RUN dotnet build "xxx.csproj" -c Release -o /app/build

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

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

Then in the build args textbox in Azure I have this:

NUGET_PAT=xxxxxxxxxxxxxxxxxxxxxxxxx

I have also set the PAT token to the following permissions as read in a post on this forum:

  • Build: Read
  • Connected server (Access endpoints): Connected server
  • Packaging (Create, read, update, and delete feeds and packages): Read

I have also set the PAT to allow all organizations as opposed to our working group, and I have tried copying a nuget.config directly into the container and all's I end up with is a 401 unauthorised.

I have also left the username set to "username" as most examples alluded to the fact that it wasn't required.

What am I doing wrong?


Solution

  • Here is the final Dockerfile that works for me in the Azure pipeline with the Docker build and push tasks:

    FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
    WORKDIR /app
    
    FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
    WORKDIR /src
    
    EXPOSE 80
    
    # run the azure credential provider and let it do its magic
    RUN curl -L https://raw.githubusercontent.com/Microsoft/artifacts-credprovider/master/helpers/installcredprovider.sh  | sh
    
    # personal access token arg 
    ARG NUGET_PAT
    
    # link to azure feed arg
    ARG AZURE_FEED
    
    # set env var for azure credential provider
    ENV VSS_NUGET_EXTERNAL_FEED_ENDPOINTS \
        "{\"endpointCredentials\": [{\"endpoint\":\"${AZURE_FEED}\", \"username\":\"docker\", \"password\":\"${NUGET_PAT}\"}]}"
    
    # debug env vars to make sure things are getting set correctly
    RUN printenv
    
    # restore private and public nuget feed
    COPY ["xxx.csproj", "."]
    RUN dotnet restore -s "${AZURE_FEED}" -s "https://api.nuget.org/v3/index.json"
    
    # build
    COPY . .
    WORKDIR "/src"
    RUN dotnet build "xxx.csproj" -c Release -o /app/build
    
    # publish
    FROM build AS publish
    RUN dotnet publish "xxx.csproj" -c Release -o /app/publish
    
    # run
    FROM base AS final
    WORKDIR /app
    COPY --from=publish /app/publish .
    ENTRYPOINT ["dotnet", "xxx.dll"]
    

    I also found that it was better to create a Variable Group in Azure with the AZURE_FEED and NUGET_PAT so the Personal Access Token and Feed can be shared amongst other pipelines.