1

I wrote an ASP.NET Core application which should run in a container using docker. This works, but the hole build process is relatively slow. The main bottleneck seems to be nuget. A lot of packages are referenced, and it take time to load all of them from the internet. This is done on every build since docker alwas start a new container.

My idea is to create a persistent dictionary on the host, where the packages are stored. So they don't have to be fetched on every build. dotnet restore has a parameter --packages where I can define a cache directory. But for this its required to pass a shared dictionary to the docker build command.

I found out that docker run has a -v parameter where i can pass /host/path:/container/path to share a folder from the host to the container. But this only works for docker run, not docker build. Also the COPY command doesn't fit here since it let me only copy files from the host to the container. First I had to copy the other way round (container to host).

So how can I create a cache directory which doesn't got disposed together with the container?

I found similar issues like this. Its composer there, but the problem of a persistent cache directory is the same. They use the -v parameter on docker run. But I can't understand how this solve the problem: In my understanding of docker, the dockerfile should build the application. This includes installing dependencies like NuGet-Packages for ASP.NET Core, bower and similar. So this should happen in the dockerfile, not when running the container.

Lion
  • 16,606
  • 23
  • 86
  • 148
  • 2
    Please read that https://blogs.msdn.microsoft.com/stevelasker/2016/09/29/building-optimized-docker-images-with-asp-net-core/ – Simon Martinelli Dec 23 '16 at 16:16
  • If anyone else stumbles across this question, I believe the answer is Buildkit and you can get more information here: [https://stackoverflow.com/a/66165135/97017](https://stackoverflow.com/a/66165135/97017) – Viper Jul 12 '22 at 13:55

1 Answers1

0

If you absolutely must restore packages within the container first then the best you can do is re-use intermediate or previously built docker images that already have the packages restored.

If you use the Visual Studio generated Dockerfile it already does the best it can to re-use the intermediate image that includes the package cache. This is accomplished by copying the .csproj file over first, restoring packages, and then copying over the source files. That way if you didn't change your package references (basically the only thing that changes in .csproj) then docker simply uses the intermediate image it created on the previous build after restoring packages.

You could also create a base image that has packages restored already and occasionally update it. Here's how you'd do that:
1. Build your Dockerfile: docker build .
2. Tag the intermediate container that has the package cache (the one created by dotnet restore): docker tag {intermediate image id} {your project name}:base-1
3. Update Dockerfile to use {your project name}:base-1 as the base image FROM {your project name}:base-1
4. If you're using a build system then publish the base image: docker publish {your project name}:base-1
5. Periodically update your base image, rolling the version number.

carlin.scott
  • 6,214
  • 3
  • 30
  • 35