Using Docker Buildkit --mount=type=cache for caching Nuget packages for .NET 5 dockerfile

Viewed 2692

Currently I am creating a dockerfile for a vue+mvc .net 5 hybrid application. For this, I need to install nodeJS, nuget packages as well install webpack. Everytime when I am trying the build the image, its taking around 30 min. I explored how can I reduce this build time, then I understand the new Docker Buildkit feature provided cache mount. But, I didn't find much samples or documentation on working with nuget packages specially.

Please can someone help me in providing any sample dockerfile which has implemented --mount=type=cache for nuget packages.

1 Answers

The key is using the same --mount=type=cache argument in all of the dockerfile RUN commands that need access to the same package cache (e.g. docker restore, docker build, docker publish).

Here's a short dockerfile example showing the same --mount=type=cache with the same id spread across separate dotnet restore/build/publish invocations. Separating the calls isn't always necessary as build will restore by default and publish will do both, but this way shows sharing the same cache across multiple commands. The cache mount declarations only appear in the dockerfile itself and don't require arguments in docker build.

The example also shows how you might use the BuildKit --mount=type=secret argument to pass in a NuGet.Config file that may be configured to access e.g. a private nuget feed. By default, secret files passed in this way appear in /run/secrets/<secret-id>, but you can change where they go via the target attribute in the docker build command. They only exist during the RUN invocation and don't remain in the final image.

# syntax=docker/dockerfile:1.2
FROM my-dotnet-sdk-image as builder
WORKDIR "/src"
COPY "path/to/project/src" .

RUN --mount=type=cache,id=nuget,target=/root/.nuget/packages \
    --mount=type=secret,id=nugetconfig \
    dotnet restore "MyProject.csproj" \
    --configfile /run/secrets/nugetconfig \
    --runtime linux-x64

RUN --mount=type=cache,id=nuget,target=/root/.nuget/packages \
    dotnet build "MyProject.csproj" \
    --no-restore \
    --configuration Release \
    --framework netcoreapp3.1 \
    --runtime linux-x64

RUN --mount=type=cache,id=nuget,target=/root/.nuget/packages \
    dotnet publish "MyProject.csproj" \
    --no-restore \
    --no-build \
    -p:PublishReadyToRun=true \
    -p:PublishReadyToRunShowWarnings=true \
    -p:TieredCompilation=false \
    -p:TieredCompilationQuickJit=false \
    --configuration Release \
    --framework netcoreapp3.1 \
    --runtime linux-x64

A sample docker build command to pass in the nugetconfig file for a private feed might be:

docker build --secret id=nugetconfig,src=path/to/nuget.config -t my-dotnet-image .

For that command, the environment variable DOCKER_BUILDKIT=1 needs to be set.

Alternatively, you can use buildx:

docker buildx build --secret id=nugetconfig,src=path/to/nuget.config -t my-dotnet-image .

Related