CSC : error CS5001: Program does not contain a static 'Main' method suitable for an entry point [/ClinicApi.csproj] in a Docker build, with the project path right at /, means the Dockerfile has no WORKDIR and the project was copied into the root folder. Add WORKDIR /src before the COPY.

The project and its Program.cs did not change. With one WORKDIR /src line the same build succeeded.

The error

PS> docker build --progress=plain --no-cache -t fix10-dn-resx .
...
#7 [3/3] RUN dotnet build -c Release
#7 0.668   Determining projects to restore...
#7 1.037   Restored /ClinicApi.csproj (in 61 ms).
#7 2.271 CSC : error CS5001: Program does not contain a static 'Main' method suitable for an entry point [/ClinicApi.csproj]
#7 2.281
#7 2.281 Build FAILED.
...

Why it happens

Read the two lines before the error. Restore succeeded (Restored /ClinicApi.csproj), so packages are not the problem; the failure comes from the compiler, CSC. And the project path in brackets is /ClinicApi.csproj, a project file sitting directly in the root folder, which is the clue to the cause. The whole build stopped quickly, after Time Elapsed 00:00:01.88.

The failing Dockerfile was three lines:

FROM mcr.microsoft.com/dotnet/sdk:10.0
COPY . .
RUN dotnet build -c Release

Without a WORKDIR, the working folder of the sdk:10.0 image was /, and COPY . . put ClinicApi.csproj and Program.cs there. A probe Dockerfile with the same FROM and COPY lines, whose RUN line ran pwd, then ls -d /Program.cs /ClinicApi.csproj, then a detailed build, printed:

#7 0.236 /
#7 0.237 /ClinicApi.csproj
#7 0.237 /Program.cs

So the file was present. Asking MSBuild for the project's Compile items settled the rest: in the root folder the list was empty, and with WORKDIR /src it held Program.cs.

#7 [3/3] RUN dotnet msbuild ClinicApi.csproj -getItem:Compile
...
#7 0.755     "Compile": []
...
#8 [4/4] RUN dotnet msbuild ClinicApi.csproj -getItem:Compile
...
#8 0.711     "Compile": [
...
#8 0.711         "Identity": "Program.cs",
#8 0.711         "FullPath": "/src/Program.cs",
...

With no source file in the project, there is no Main, which is what CS5001 says. The test does not show why the root folder gave an empty list.

The fix

FROM mcr.microsoft.com/dotnet/sdk:10.0
WORKDIR /src
COPY . .
RUN dotnet build -c Release
PS> docker build -q -f Dockerfile.fixed -t fix10-dn-resxfix .
sha256:ddc994970e01d137f51975f0997ab4373769c8c0764629446fcc17ae2acc5f13
PS> docker run --rm --name fix10-dn-x1 fix10-dn-resxfix ls /src
ClinicApi.csproj
Dockerfile
Dockerfile.fixed
Program.cs
bin
obj

The build passed and left bin and obj next to the project in /src. The listing also shows the two Dockerfiles copied in: with no .dockerignore in the folder, COPY . . took everything.

How it was reproduced

A console project (ClinicApi.csproj with the default console settings and a one-line top-level Program.cs) built with docker build --progress=plain --no-cache -t fix10-dn-resx . on mcr.microsoft.com/dotnet/sdk:10.0 (SDK 10.0.302), Docker engine 29.9.3 on Windows 11.

Frequently asked

Why does dotnet build fail with CS5001 only in Docker?
In the test the Dockerfile had no WORKDIR, so the project was copied to the root folder and built as /ClinicApi.csproj. The compiler found no entry point although /Program.cs existed.
Do I need WORKDIR in a .NET Dockerfile?
In this test, yes. Adding WORKDIR /src before COPY . . turned the failing build into a passing one with no other change.
Does COPY . . copy the Dockerfile too?
Yes, in the test the Dockerfiles were in the build context and ended up in /src next to the project files.

CS5001 outside Docker has other causes: CS5001 Program does not contain a static Main method. More decoded errors in the Fixes category.