windowsvisual-studiodockercommand-line-interfacewindows-subsystem-for-linux

Docker gets error "failed to compute cache key: not found" - runs fine in Visual Studio


I've generated a Dockerfile with Visual Studio. It runs in Visual Studio just fine and now I'm trying to build it from Windows itself (docker build ., and I tried many combinations). Yet I get the following error:

> [build 3/7] COPY [client/client.csproj, client/]:
------
failed to compute cache key: "/client/client.csproj" not found: not found

When I change copy to ./client.csproj it does continue and then I get:

 => ERROR [build 7/7] RUN dotnet build "client.csproj" -c Release -o /app/build                3.3s
------
> [build 7/7] RUN dotnet build "client.csproj" -c Release -o /app/build:
#15 0.652 Microsoft (R) Build Engine version 16.8.3+39993d9d for .NET
#15 0.652 Copyright (C) Microsoft Corporation. All rights reserved.
#15 0.652
#15 1.169   Determining projects to restore...
#15 1.483   All projects are up-to-date for restore.
#15 3.231 CSC : error CS5001: Program does not contain a static 'Main' method suitable for an entry point [/src/client/client.csproj]
#15 3.240
#15 3.240 Build FAILED.
#15 3.240
#15 3.240 CSC : error CS5001: Program does not contain a static 'Main' method suitable for an entry point [/src/client/client.csproj]
#15 3.240     0 Warning (5)
#15 3.240     1 Error (5)
#15 3.240
#15 3.240 Time Elapsed 00:00:02.51
-----
executor failed running [/bin/sh -c dotnet build "client.csproj" -c Release -o /app/build]: exit code: 1

What am I doing wrong? I changed Docker Linux to Windows, changed WSL, and restarted everything.

#See https://aka.ms/containerfastmode to understand how Visua...

FROM mcr.microsoft.com/dotnet/aspnet:5.0-buster-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:5.0-buster-slim AS build
WORKDIR /src
COPY ["client/client.csproj", "client/"]
RUN dotnet restore "client/client.csproj"
COPY . .
WORKDIR "/src/client"
RUN dotnet build "client.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "client.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet', "client.dll"]

Solution

  • The way Visual Studio does it is a little bit odd.

    Instead of launching docker build in the folder with the Dockerfile, it launches in the parent folder and specifies the Dockerfile with the -f option.

    I was using the demo project (trying to create a minimal solution for another question) and struck the same situation.

    Setup for my demo project is

    \WorkerService2  ("solution" folder)
       +- WorkerService2.sln
       +- WorkserService2  ("project" folder)
           +- DockerFile
           +- WorkerService2.csproj
           +- ... other program files
    

    So I would expect to go

    cd \Workerservice2\WorkerService2
    docker build .
    

    But I get your error message.

     => ERROR [build 3/7] COPY [WorkerService2/WorkerService2.csproj, WorkerService2/]                                                                                                                        0.0s
    ------
     > [build 3/7] COPY [WorkerService2/WorkerService2.csproj, WorkerService2/]:
    ------
    failed to compute cache key: "/WorkerService2/WorkerService2.csproj" not found: not found
    

    Instead, go to the parent directory, with the .sln file and use the docker -f option to specify the Dockerfile to use in the subfolder:

    cd \Workerservice2
    docker build -f WorkerService2\Dockerfile --force-rm -t worker2/try7 .
    
    docker run -it worker2/try7    
    

    Note the final dot on the docker build command.

    For docker the final part of the command is the location of the files that Docker will work with. Usually this is the folder with the Dockerfile in, but that's what's different about how VS does it. In this case the dockerfile is specified with the -f. Any paths (such as with the COPY instruction in the dockerfile) are relative to the location specified. The . means "current directory", which in my example is \WorkerService2.

    I got to this stage by inspecting the output of the build process, with verbosity set to Detailed. If you choose Tools / Options / Projects and Solutions / Build and Run you can adjust the build output verbosity, I made mine Detailed.


    I think I've worked out why Visual Studio does it this way. It allows the project references in the same solution to be copied in.

    If it was set up to do docker build from the project folder, docker would not be able to COPY any of the other projects in the solution in. But the way this is set up, with current directory being the solution folder, you can copy referenced projects (subfolders) into your docker build process.