2

I have been trying to get docker to pull from a private nuget feed which is hosted within Azure Devops, but I consistently get a 401 unauthorized error. I have looked at numerous other answers and resources, but all of which have not helped. My dockerfile script is the following

# escape=`

FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build-env
WORKDIR /src
EXPOSE 80
EXPOSE 443

ARG FEED_URL
ARG FEED_ACCESSTOKEN

# Install powershell via dotnet
RUN dotnet tool install --global PowerShell --version 7.0.0
SHELL ["pwsh", "-command"]

## CURRENT ERROR - "-AddNetfx" - NOT CONSIDERED AN ARGUMENT, ALTHOUGH IT IS (CAN BE SEEN IN THE SCRIPT ENTRY) ##
# Install credprovider which is required for accessing private artifact repository
RUN Invoke-WebRequest https://raw.githubusercontent.com/microsoft/artifacts-credprovider/master/helpers/installcredprovider.ps1 -OutFile installcredprovider.ps1; `
    .\installcredprovider.ps1 -AddNetfx; `
    del installcredprovider.ps1
#################################################################################################################

# Copy csproj and sln files
COPY ["Abstractions/*.csproj", "./Abstractions/"]
COPY ["AdminServicesPortal/*.csproj", "./AdminServicesPortal/"]
COPY ["DataInterface/*.csproj", "./DataInterface/"]
COPY ["Resources/*.csproj", "./Resources/"]

# Need to copy over docker NuGet packages
COPY "AdminServicesPortal/nuget.config" "AdminServicesPortal/"

# Enable session token cache
ENV NUGET_CREDENTIALPROVIDER_SESSIONTOKENCACHE_ENABLED true


ENV VSS_NUGET_EXTERNAL_FEED_ENDPOINTS `
    "{`"endpointCredentials`": [{`"endpoint`":`"https://pkgs.dev.azure.com/ORG/PROJECT/_packaging/FEED/nuget/v3/index.json`", `"username`":`"USER`", `"password`":`"PAT`"}]}"
RUN echo $Env:VSS_NUGET_EXTERNAL_FEED_ENDPOINTS

# Restore dependencies before copying everything else over
RUN dotnet restore "AdminServicesPortal/Portal.csproj"

# Copy the rest of the files required for a build
# Note that this is separate, because we should stop building
# the container if we do not have all required dependencies
COPY Abstractions/. ./Abstractions/
COPY AdminServicesPortal/. ./AdminServicesPortal/
COPY DataInterface/. ./DataInterface/
COPY Resources/. ./Resources/

WORKDIR "/src/AdminServicesPortal"
RUN dotnet build "Portal.csproj" -c Release -o /app/build

# Publish application
FROM build-env AS publish
RUN dotnet publish "Portal.csproj" -c Release -o /app/publish

# Runtime environment for container
FROM build-env AS final
WORKDIR /app
COPY --from=build /app/publish .
ENTRYPOINT ["dotnet", "MPX.AdminServices.Portal.dll"]

The error I get from Visual Studio is the following

2>  Failed to restore C:\src\Resources\Resources.csproj (in 2.99 sec).
2>C:\Program Files\dotnet\sdk\3.1.404\NuGet.targets(128,5): error : Unable to load the service index for source https://pkgs.dev.azure.com/{ORG}/{PROJECT}/_packaging/{FEED}/nuget/v3/index.json. [C:\src\AdminServicesPortal\Portal.csproj]
2>C:\Program Files\dotnet\sdk\3.1.404\NuGet.targets(128,5): error :   Response status code does not indicate success: 401 (Unauthorized). [C:\src\AdminServicesPortal\Portal.csproj]

From what I can tell in the link below; my dockerfile script should work

https://github.com/dotnet/dotnet-docker/blob/master/documentation/scenarios/nuget-credentials.md#using-the-azure-artifact-credential-provider

To ensure it wasn't an issue with the PAT of the user not having access, I gave them access to everything across the whole entire organisation. Any help would be greatly appreciated!

Note #1: My current suspicion is that there are some additional parameters I might need to pass, since the private nuget feed is for a project rather than the entire organisation?

Note #2: I ran the following PowerShell command (https://learn.microsoft.com/en-us/azure/devops/artifacts/tutorials/private-powershell-library?view=azure-devops#package-and-publish-the-module) which worked fine, so I am even more confused to why my dockerfile script does not work.

nuget sources Add -Name "PowershellModules" -Source "https://pkgs.dev.azure.com/<org_name>/_packaging/<feed_name>/nuget/v3/index.json" -username "<user_name>" -password "<personal_access_token(PAT)>"
Andy
  • 339
  • 3
  • 17

2 Answers2

3

You can check out below workarounds without using NuGet credential plugin.

1, Use dotnet cli to add credentials to the nuget source in your docker file. And then pass the $PAT in the build arguments (ie. --build-arg PAT=$PAT ):

ARG PAT
COPY . .
RUN dotnet nuget add source "your-source-url" --name "source-name" --username "useless" --password "$PAT" --store-password-in-clear-text
RUN dotnet restore

2, You can also try adding the credentials to the config file using the nuget command. And include the nuget.config which has the credentials in the build context. And copy the nuget.config in your docker file . See below:

sources Add -Name "MyPackages" -Source "https://my.pkgs.visualstudio.com/_packaging/MyPackages/nuget/v3/index.json" -username any -password $PAT -ConfigFile Source/Nuget.config -StorePasswordInClearText

Copy the nuget.config in the docker file, You can delete the nuget.config file when the restore is complete:

COPY *.csproj .
COPY ./nuget.config .
RUN dotnet restore
RUN rm nuget.config

You can refer to my answer to this similar thread that using azure nuget feed in the docker container in Azure pipelines.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Levi Lu-MSFT
  • 27,483
  • 2
  • 31
  • 43
  • Thanks for the response! I ended up throwing the login details in the NuGet.config file, as per the thread and copying it over, which worked as expected. – Andy Nov 16 '20 at 06:37
0

Similar to Levi's post, this is my solution that doesn't physically store the password in the nuget.config file on the file system but adds it, restores then deletes it in one action so it isn't left behind in one of the temporary docker layers for some-one to fish out.

COPY *.csproj .
COPY ./nuget.config .
RUN dotnet nuget add source https://pkgs.dev.azure.com/<replace>/<replace>/_packaging/<replace>/nuget/v3/index.json --name <source name> --username '<user name>' --password ${<PAT>} --configfile <nuget.config> --store-password-in-clear-text && \
        dotnet restore && \
        rm <nuget.config>
samneric
  • 3,038
  • 2
  • 28
  • 31