我试图创建一个.NET 6项目的Docker镜像,但在使用+12GB
的RAM时,在dotnet restore
期间卡住了。
我的项目结构是:
- backend/
- frontend/
字符串
在这里,我只是在backend/
中执行docker build .
,
的数据
这是当前控制台的输出:
[+] 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
型
我的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>
型
这是我的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:
这是一个通过的结果(1小时)建设:
4条答案
按热度按时间jslywgbw1#
问题出在我的
.csproj
上字符串
我把它改成:
型
y0u0uwnf2#
在另一种情况下,我以为我的应用程序在还原时卡住了,但它在构建时卡住了。您还可以将以下to标志添加到dotnet restore命令和dotnet build命令中,以在构建运行时获取更多信息-v diag
字符串
请记住,这是在Dockerfile中。我所做的是首先在dotnetrestore上放置-v diag,然后在查看输出后意识到它实际上正在通过该阶段。接下来我将其从restore中删除,并在构建行上放置相同的标志,这是因为有很多信息正在输出,所以我只是想限制输出。
对我来说,最后一句话是
warnaserror+:NU1605(TaskId:105)
在谷歌搜索后,
依赖项包指定了一个版本约束,该版本约束的包版本高于还原最终解决的版本。
https://learn.microsoft.com/en-us/nuget/reference/errors-and-warnings/nu1605
因此,尽管我的应用程序在开发中构建和运行良好,但我依赖于一个依赖于.Net Core 3.1的库,但我使用的是.Net 6,并且正在构建的Docker容器也是在.Net 6之上构建的
别问我它是怎么工作的,它就是这么做的。
我从阅读这篇文章中得到了-v标志,它也有助于解决整个挂起问题https://tsuyoshiushio.medium.com/solving-flaky-dotnet-restore-issue-only-on-docker-failed-to-retrieve-information-cd847573c3f2
有关可以在dotnet命令上放置的含义和选项的列表,
eg -v diag是--verbosity diagnostic的缩写(因为你想诊断一个问题,所以有很多信息),你可以查看https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-restore#options
brvekthn3#
在GitHub issue(可能)由海报在这里,有一个评论,其中指出:
由于项目被放置在容器根目录下的目录中,因此该路径会导致扫描整个容器的文件系统。这会大大降低速度。
换句话说,
COPY
和RUN dotnet restore
命令可能是在Docker容器的根目录下执行的,这会导致.NET扫描整个容器文件系统,从而导致restore
命令“冻结”。一个潜在的解决方案是确保您使用
WORKDIR
指令将文件放入新目录。字符串
请注意,您需要更新后续作业以指向新路径(在上面的示例中为“/app”)。
lskq00tm4#
在我的例子中,
.csproj
文件不包含任何<Watch/>
标签,但dotnet restore
步骤仍然卡住了。我在GitHub的评论中找到了解决方案。在Dockerfile中,而不是使用版本6.0:字符串
我用的是8.0版本:
型