Docker build complains it can't find nuget fallback package folder

Viewed 11260

I'm following the tutorial at https://docs.microsoft.com/en-us/dotnet/core/docker/docker-basics-dotnet-core#dockerize-the-net-core-application in learning to containerise .net core applications into Docker.

Other than changing the Dockerfile to point at microsoft/dotnet:2.1-sdk as a base image, and adding a RUN dotnet --info line to get version/environment information, everything else is the same. However, I'm getting an error on the dotnet publish step:

Step 7/8 : RUN dotnet publish -c Release -o out
 ---> Running in 6739267c7581
Microsoft (R) Build Engine version 15.8.166+gd4e8d81a88 for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.

  Restore completed in 34.46 ms for /app/Hello.csproj.
/usr/share/dotnet/sdk/2.1.401/Sdks/Microsoft.NET.Sdk/targets/Microsoft.PackageDependencyResolution.targets(198,5): error MSB4018: The "ResolvePackageAssets" task failed unexpectedly. [/app/Hello.csproj]
/usr/share/dotnet/sdk/2.1.401/Sdks/Microsoft.NET.Sdk/targets/Microsoft.PackageDependencyResolution.targets(198,5): error MSB4018: NuGet.Packaging.Core.PackagingException: Unable to find fallback package folder 'C:\Program Files\dotnet\sdk\NuGetFallbackFolder'. [/app/Hello.csproj]
/usr/share/dotnet/sdk/2.1.401/Sdks/Microsoft.NET.Sdk/targets/Microsoft.PackageDependencyResolution.targets(198,5): error MSB4018:    at NuGet.Packaging.FallbackPackagePathResolver..ctor(String userPackageFolder, IEnumerable`1 fallbackPackageFolders) [/app/Hello.csproj]
/usr/share/dotnet/sdk/2.1.401/Sdks/Microsoft.NET.Sdk/targets/Microsoft.PackageDependencyResolution.targets(198,5): error MSB4018:    at Microsoft.NET.Build.Tasks.NuGetPackageResolver.CreateResolver(LockFile lockFile, String projectPath) [/app/Hello.csproj]
/usr/share/dotnet/sdk/2.1.401/Sdks/Microsoft.NET.Sdk/targets/Microsoft.PackageDependencyResolution.targets(198,5): error MSB4018:    at Microsoft.NET.Build.Tasks.ResolvePackageAssets.CacheWriter..ctor(ResolvePackageAssets task, Stream stream) [/app/Hello.csproj]
/usr/share/dotnet/sdk/2.1.401/Sdks/Microsoft.NET.Sdk/targets/Microsoft.PackageDependencyResolution.targets(198,5): error MSB4018:    at Microsoft.NET.Build.Tasks.ResolvePackageAssets.CacheReader.CreateReaderFromDisk(ResolvePackageAssets task, Byte[] settingsHash) [/app/Hello.csproj]
/usr/share/dotnet/sdk/2.1.401/Sdks/Microsoft.NET.Sdk/targets/Microsoft.PackageDependencyResolution.targets(198,5): error MSB4018:    at Microsoft.NET.Build.Tasks.ResolvePackageAssets.CacheReader..ctor(ResolvePackageAssets task) [/app/Hello.csproj]
/usr/share/dotnet/sdk/2.1.401/Sdks/Microsoft.NET.Sdk/targets/Microsoft.PackageDependencyResolution.targets(198,5): error MSB4018:    at Microsoft.NET.Build.Tasks.ResolvePackageAssets.ReadItemGroups() [/app/Hello.csproj]
/usr/share/dotnet/sdk/2.1.401/Sdks/Microsoft.NET.Sdk/targets/Microsoft.PackageDependencyResolution.targets(198,5): error MSB4018:    at Microsoft.NET.Build.Tasks.ResolvePackageAssets.ExecuteCore() [/app/Hello.csproj]
/usr/share/dotnet/sdk/2.1.401/Sdks/Microsoft.NET.Sdk/targets/Microsoft.PackageDependencyResolution.targets(198,5): error MSB4018:    at Microsoft.NET.Build.Tasks.TaskBase.Execute() [/app/Hello.csproj]
/usr/share/dotnet/sdk/2.1.401/Sdks/Microsoft.NET.Sdk/targets/Microsoft.PackageDependencyResolution.targets(198,5): error MSB4018:    at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute() [/app/Hello.csproj]
/usr/share/dotnet/sdk/2.1.401/Sdks/Microsoft.NET.Sdk/targets/Microsoft.PackageDependencyResolution.targets(198,5): error MSB4018:    at Microsoft.Build.BackEnd.TaskBuilder.ExecuteInstantiatedTask(ITaskExecutionHost taskExecutionHost, TaskLoggingContext taskLoggingContext, TaskHost taskHost, ItemBucket bucket, TaskExecutionMode howToExecuteTask) [/app/Hello.csproj]
The command '/bin/sh -c dotnet publish -c Release -o out' returned a non-zero code: 1

So far the only thing I can find on the subject is some github issues requesting that the fallback folder is ditched in Docker as it bloats the container. At this stage I'm not concerned too much about bloat, I just want it to build a hello world application.


In case it is helpful the dotnet --info command returned the following:

Step 3/8 : RUN dotnet --info
 ---> Running in 17dad2f04a7e
.NET Core SDK (reflecting any global.json):
 Version:   2.1.401
 Commit:    91b1c13032

Runtime Environment:
 OS Name:     debian
 OS Version:  9
 OS Platform: Linux
 RID:         debian.9-x64
 Base Path:   /usr/share/dotnet/sdk/2.1.401/

Host (useful for support):
  Version: 2.1.3
  Commit:  124038c13e

.NET Core SDKs installed:
  2.1.401 [/usr/share/dotnet/sdk]

.NET Core runtimes installed:
  Microsoft.AspNetCore.All 2.1.3 [/usr/share/dotnet/shared/Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.App 2.1.3 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 2.1.3 [/usr/share/dotnet/shared/Microsoft.NETCore.App]

To install additional .NET Core runtimes or SDKs:
  https://aka.ms/dotnet-download
5 Answers

The problem is some lingering files in your bin and obj directories, which you don't need to build your app from source. Therefore I think the best solution is to add the bin and obj directories into a .dockerignore file, which will exclude those folders from copying into your Docker context, resulting in a small performance boost. Here's what my .dockerignore file looks like for dotnet apps:

.dockerignore
.env
.git
.gitignore
.vs
.vscode
docker-compose.yml
docker-compose.*.yml
**/bin
**/obj
bin/
obj/

This is likely due to the obj\project.assests.json file that is generated by Visual Studio when you open the project. If you look in there, you'll find reference to your NuGet package folders in your Windows system.

e.g.

"packageFolders": {
  "C:\\Users\\<UserName>\\.nuget\\packages\\": {},
  "C:\\Program Files\\dotnet\\sdk\\NuGetFallbackFolder": {}
},

A simple workaround is to add a step in your Dockerfile to delete the bin and obj files before it runs any restore, build or test step. One way to do that is to make use of the find program:

find -type d -name bin -prune -exec rm -rf {} \; && find -type d -name obj -prune -exec rm -rf {} \;

Using the Dockerfile from the tutorial you linked to as an example, that would look something like this:

FROM microsoft/dotnet:2.1-sdk
WORKDIR /app

# copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore

# copy and build everything else
COPY . ./
RUN find -type d -name bin -prune -exec rm -rf {} \; && find -type d -name obj -prune -exec rm -rf {} \;
RUN dotnet publish -c Release -o out
ENTRYPOINT ["dotnet", "out/Hello.dll"]

if your docker container is of the linux family, add this flag -r linux-x64 to the publish command, this flag should cover building for "(Most desktop distributions like CentOS, Debian, Fedora, Ubuntu, and derivatives)"; so the publish command should look like this RUN dotnet publish -r linux-x64 -c Release -o out for other RIDs refer to this https://docs.microsoft.com/en-us/dotnet/core/rid-catalog

You could add a .dockerignore file so that it ignores any obj directories created locally when building the image with docker, e.g. put this in .dockerignore. This works for me.

*/obj/*

In my case, after checking that with all of these responses the problem persisted, the only solution was to restart docker desktop.

Related