I recently had to add a private NuGet package feed to my Azure DevOps build pipeline that creates a Docker container. It looks like a lot of folks are struggling to do the same thing so I put some notes together on how I was able to get it to work without adding secrets to my source control.
The challenge comes in when the docker build tries to execute a NuGet restore. The private repository needs credentials and the build fails with NuGet restore error NU1102: Unable to find package. The most common solutions I found online included configuring a nuget.config
with the credentials in it. This means putting the credentials in source control (not a good practice) or generating a nuget.config
file as part of the build process from pipeline variables. The first option was a non-starter and hacking together a script to generate the nuget.config
seemed overly complex to maintain. With this knowledge, I set off to piece together a solution that did not require storing secrets in source control and would be easy to live with.
My solution is to perform a NuGet restore as a build step in the pipeline which copies the packages to the agent. I then copy the packages to the build container and set the nuget.config
to use the folder on the build container as the source for the packages. This means my nuget.config
does not contain any secrets and can be stored in source control alongside my Docker file.
Below are detailed steps on implementing this solution.
steps:
- task: NuGetToolInstaller@0
displayName: 'Use NuGet 4.7.1'
inputs:
versionSpec: 4.7.1
Important: Under advanced set the Destination directory to NugetPackage
(this name needs to align with the one you use in the nuget.config
file)
steps:
- task: NuGetCommand@2
displayName: 'NuGet restore'
inputs:
vstsFeed: '{your feed here}'
restoreDirectory: NugetPackage
nuget
.configfile in the same folder as your Dockerfile that is configured to use the local package source named
NugetPackage`Note: In my example the .sln file, Dockerfile and nuget.config all live adjacent in the root folder of the solution.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="local" value="NugetPackage" />
</packageSources>
</configuration>
FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
WORKDIR /app
FROM microsoft/dotnet:2.1-sdk AS build
WORKDIR /src
COPY . . <--copies the nuget packages to the build container
RUN dotnet restore <--this restore will use the nuget.config
RUN dotnet build -c Release -o /app --no-restore
FROM build AS publish
RUN dotnet publish -c Release -o /app --no-restore
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "bradjolicoeur.web.dll"] <--make sure you change to reference your app