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"]
My net usage:
This is a pass result (1 hour) building:
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>
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With