Reputation: 635
I'm trying to create a docker image of a .NET 6 project, but is stuck during dotnet restore
while using +12GB
of RAM.
My project structure is:
- backend/
- frontend/
Where I just cd
in the backend/
and run docker build .
This is the output of the console currently:
[+] Building 276.4s (15/19)
=> [internal] load .dockerignore 0.0s
=> [internal] load build definition from Dockerfile.server 0.0s
=> [internal] load metadata for mcr.microsoft.com/dotnet/sdk:6.0 0.6s
=> [internal] load metadata for mcr.microsoft.com/dotnet/aspnet:6.0 0.6s
=> [stage-1 1/3] FROM mcr.microsoft.com/dotnet/aspnet:6.0@sha256:9ca180a6a0a0ec39209437e5e0986caf17b7d91473d9c34bb6191e47a7b500aa 0.0s
=> [build-env 1/6] FROM mcr.microsoft.com/dotnet/sdk:6.0@sha256:ca4344774139fabfb58eed70381710c8912900d92cf879019d2eb52abc307102 0.0s
=> [internal] load build context 0.2s
=> => transferring context: 3.69kB 0.2s
=> CACHED [stage-1 2/3] WORKDIR /app 0.0s
=> CACHED [build-env 2/6] WORKDIR /app 0.0s
=> CACHED [build-env 3/6] COPY *.csproj ./ 0.0s
=> [build-env 4/6] RUN dotnet restore 270.2s
My csproj:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>1701;1702;1705;1591;10102;</NoWarn>
<DefaultItemExcludes>**\node_modules\**;$(DefaultItemExcludes)</DefaultItemExcludes>
</PropertyGroup>
<ItemGroup>
<Watch Include="..\**\*.env" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="AutoMapper" Version="10.1.1" />
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="8.1.1" />
<PackageReference Include="BCrypt.Net-Next" Version="4.0.2" />
<PackageReference Include="dotenv.net" Version="3.1.1" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.0" />
<PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="6.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="6.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.Certificate" Version="5.0.12" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
</ItemGroup>
</Project>
This is my Dockerfile:
# syntax=docker/dockerfile:1
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build-env
WORKDIR /app
ARG Config=Debug
ENV ASPNETCORE_URLS=http://*:5000
# Copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore
# Copy everything
COPY . .
# Publish
RUN dotnet publish -c ${Config} -o /app/publish
# Build runtime image
FROM mcr.microsoft.com/dotnet/aspnet:6.0
WORKDIR /app
COPY --from=build-env /app/publish .
ENTRYPOINT ["dotnet", "myapp.dll"]
This is a pass result (1 hour) building:
Upvotes: 3
Views: 8526
Reputation: 1109
On the GitHub issue (probably) made by the poster here, there is a comment which states the following:
Because the project is being placed in a directory that is directly under the root of the container, this path causes a scan of the entire container's file system. This slows things down tremendously.
In other words, the COPY
and RUN dotnet restore
command are potentially being made in the root of the Docker container, which causes .NET to scan the entire container file system, which causes the restore
command to "freeze up".
A potential solution is to ensure you are placing the files into a new directory by using the WORKDIR
instruction.
WORKDIR /app
COPY *.csproj .
RUN dotnet restore
Note, that you will need to update subsequent jobs to point to the new path (in the example above, '/app').
Upvotes: 1
Reputation: 1573
In my case the .csproj
file didn't contain any <Watch/>
tag but the dotnet restore
step stuck anyway. I found the solution in this GitHub comment. In Dockerfile, instead of using version 6.0:
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
I used version 8.0:
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
Upvotes: -2
Reputation: 101
In a different case, I thought my application was stuck on the restore, however it was stuck on the build. You can also add the following to flags to your dotnet restore command as well as your dotnet build command to get more information when your build is running -v diag
# RUN dotnet restore "Myproject.Ticketing/Myproject.Ticketing.csproj"
# So instead of just the line at the top, add the -v diag flag like below
RUN dotnet restore -v diag "Myproject.Ticketing/Myproject.Ticketing.csproj"
RUN dotnet build "Myproject.Ticketing.csproj" -c Release -o /app/build -v diag
Remember, this is in the Dockerfile. What I did was I first put -v diag on the dotnetrestore and that's when I realized after looking at the output that it was actually passing that stage. Next I removed it from the restore and put the same flag on the build line, this is because there was just a lot of information being output, so I just wanted to limit the output.
Well, the conclusion was that, for me, the last phrase written on the output was
warnaserror+:NU1605 (TaskId:105)
Which after googling gave me
A dependency package specified a version constraint on a higher version of a package than restore ultimately resolved.
https://learn.microsoft.com/en-us/nuget/reference/errors-and-warnings/nu1605
So although my application was building and working great in development, there was a library I was depending on that depends on .Net Core 3.1 but yet I am using .Net 6, and the docker container being built is also building on top of .Net 6
Don't ask me how it works, it just did.
I got the -v flag from reading this article which also helps with the whole hanging problem https://tsuyoshiushio.medium.com/solving-flaky-dotnet-restore-issue-only-on-docker-failed-to-retrieve-information-cd847573c3f2
For a list of the meanings and options you can put on the dotnet command,
eg -v diag is short for --verbosity diagnostic (so lots of info since you want to diagnose a proble) you can view https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-restore#options
Upvotes: 2
Reputation: 635
Solved, the problem was in my .csproj
<ItemGroup>
<Watch Include="..\**\*.env" />
</ItemGroup>
I changed it to:
<ItemGroup>
<Watch Include="..\**\*.env" Condition="'$(DOTNET_RUNNING_IN_CONTAINER)' != 'true'" />
</ItemGroup>
Upvotes: 3