TL;DR:
When I build my .NET 6 ASP.NET console app locally, the restore uses the versions of my dependencies that I specify, but when I build within the official .NET 6 docker image, it downgrades the packages to old and incompatible versions suitable for old versions of the .NET Framework. Please help!
I have a .NET 6 ASP.NET WebAPI app that runs as a self hosted console application in a docker container. It works as expected when built and run locally, but when I attempt to build it using the official microsoft .NET 6 image, it downgrades several of my packages to an old incompatible version. I’m using Central Package Management.
Here’s the dockerfile – pretty vanilla:
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 5000
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["src/simul8.runtime.host/simul8.runtime.host.csproj", "src/simul8.runtime.host/"]
COPY ["src/simul8.core/simul8.core.csproj", "src/simul8.core/"]
COPY ["src/simul8.metamodel/simul8.metamodel.csproj", "src/simul8.metamodel/"]
COPY ["src/simul8.metamodel.metadata/simul8.metamodel.metadata.csproj", "src/simul8.metamodel.metadata/"]
COPY ["src/simul8.runtime/simul8.runtime.csproj", "src/simul8.runtime/"]
RUN dotnet restore "src/simul8.runtime.host/simul8.runtime.host.csproj"
COPY . .
WORKDIR "/src/src/simul8.runtime.host"
RUN dotnet build "simul8.runtime.host.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "simul8.runtime.host.csproj" -c Release -o /app/publish /p:UseAppHost=false
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "simul8.runtime.host.dll"]
The csproj
file for the project simul8.metamodel
, which is one of the failure points:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace>Simul8.Metamodel</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Antlr4.Runtime.Standard" />
</ItemGroup>
<ItemGroup>
<None Remove="ASTast.nodes.tt" />
</ItemGroup>
<ItemGroup>
<Content Include="ASTast.nodes.tt" />
</ItemGroup>
</Project>
It’s the Antlr4.Runtime.Standard
package that is being downgraded. In the central package version file, I ask for 4.10.1
:
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Antlr4.Runtime.Standard" Version="4.10.1" />
<PackageVersion Include="AutoFixture">
<Version>4.17.0</Version>
</PackageVersion>
<PackageVersion Include="AutoFixture.AutoMoq" Version="4.17.0" />
<PackageVersion Include="AutoFixture.NUnit3">
<Version>4.17.0</Version>
</PackageVersion>
<PackageVersion Include="AutоFiхture.NUnit3" Version="4.17.0" />
. . . snip . . .
</ItemGroup>
</Project>
But when I run a docker buildx bake -f docker-compose.yml
in powershell or WSL – after a full system prune – I get errors like the following:
/src/src/simul8.core/simul8.core.csproj : warning NU1604: Project dependency Antlr4.Runtime.Standard does not contain an inclusive lower bound.
Include a lower bound in the dependency version to ensure consistent restore results. [/src/src/simul8.runtime.host/simul8.runtime.host.csproj]
/src/src/simul8.core/simul8.core.csproj : warning NU1701: Package 'Antlr4.Runtime.Standard 4.6.0' was restored using '.NETFramework,Version=v4.6.1,
.NETFramework,Version=v4.6.2, .NETFramework,Version=v4.7, .NETFramework,Version=v4.7.1, .NETFramework,Version=v4.7.2, .NETFramework,Version=v4.8,
.NETFramework,Version=v4.8.1' instead of the project target framework 'net6.0'. This package may not be fully compatible with your project.
[/src/src/simul8.runtime.host/simul8.runtime.host.csproj]
My understanding from the docs was that setting an explicit version like 4.10.1
is the same as setting a lower bound. I also tried using 4.10.*
and [4.10.1, )
, but it made no difference.
Here are the .NET SDKs installed locally on my machine (they are all net6.0
compatible)
$ dotnet --list-sdks in pwsh at 11:03:44
6.0.201 [C:Program Filesdotnetsdk]
6.0.203 [C:Program Filesdotnetsdk]
6.0.300 [C:Program Filesdotnetsdk]
6.0.302 [C:Program Filesdotnetsdk]
6.0.400-preview.22330.6 [C:Program Filesdotnetsdk]
I’m building locally on Microsoft Visual Studio Professional 2022 (64-bit) Version 17.3.0 Preview 5.0
The version 4.6.0
of the ANTLR4 runtime package is indeed not compatible with my code, and I can’t roll back to using it, since there are features in v4.10 that I depend on.
What’s happening?
2
Answers
Posting an answer myself, in case it proves to be useful to others.
The solution for me was to remove the standard Visual Studio generated multi-stage docker file. As a (presumably) efficiency step, the generated approach was to transfer the project dependencies into the image separately, and then
dotnet restore
the project being built. For whatever reason, this had the result of confusing restore, and leading to the downgrade.Here's the simpler dockerfile that worked in the end:
It’s a bit late, since you’ve found the workaround. But for those who doesn’t want to bloat the build context in the similar situations:
To have the Central Package Management working you need to explicitly copy the Directory.Packages.props file and place it alongside the csproj/sln file you are going to restore.