.NET容器因依赖文件未找到持续重启,请求排查方案
.NET容器在Ubuntu 22.04持续重启,提示找不到Microsoft.Extensions.DependencyInjection.Abstractions 8.0.0.0
问题场景
本地MacOS 14环境下使用Docker Compose可正常启动所有容器,但生产服务器Ubuntu 22.04中某.NET容器持续重启,抛出以下错误日志:
File name: 'Microsoft.Extensions.DependencyInjection.Abstractions, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60' myapp-api-1 | at Program.<Main>$(String[] args) myapp-api-1 | at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine) myapp-api-1 | at Program.<Main>$(String[] args) myapp-api-1 | at Program.<Main>(String[] args) myapp-api-1 | Unhandled exception. System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.Extensions.DependencyInjection.Abstractions, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. The system cannot find the file specified.
相关信息
- 代码中仅显式引用
Microsoft.Extensions.DependencyInjection.Abstractions7.0.0版本:<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="7.0.0" /> - 容器始终处于
restarting状态,无法直接进入容器查看内部文件 - 容器镜像的Dockerfile定义:
FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base WORKDIR /app # Set the base image to the official .NET Core SDK image FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build WORKDIR /src COPY . . # Restore dependencies RUN dotnet restore "MyApp.Api/MyApp.Api.csproj" RUN dotnet restore "MyApp.Application/MyApp.Application.csproj" RUN dotnet restore "MyApp.Contracts/MyApp.Contracts.csproj" RUN dotnet restore "MyApp.Domain/MyApp.Domain.csproj" RUN dotnet restore "MyApp.Infrastructure/MyApp.Infrastructure.csproj" # Build the app RUN dotnet build "MyApp.sln" -c Release -o /app/build # Publish the app FROM build AS publish RUN dotnet publish "MyApp.sln" -c Release -o /app/publish # Set the final image FROM base AS final WORKDIR /app COPY --from=publish /app/publish . COPY JsonSeed ../JsonSeed ENTRYPOINT ["dotnet", "MyApp.Api.dll"] - Docker Compose中的服务定义:
api: build: ./dotnet restart: always environment: DB_HOST: ${DB_HOST} DB_PORT: ${DB_PORT} DB_NAME: ${DB_NAME} DB_USERNAME: ${DB_USERNAME} DB_PASSWORD: ${DB_PASSWORD} MIGRATE: ${MIGRATE} PORT: ${PORT} ports: - "127.0.0.1:${PORT}:${PORT}" networks: - myapp-network depends_on: - db
可能原因
- 间接依赖版本冲突:某个第三方NuGet包隐式依赖了8.0.0版本的
Microsoft.Extensions.DependencyInjection.Abstractions,本地构建时绑定重定向自动处理了版本差异,但容器环境中未生效。 - Docker构建缓存污染:生产服务器上的镜像构建使用了旧缓存,导致依赖包未正确更新,或基础镜像(7.0版ASP.NET/SDK)意外引入了8.0版本的依赖。
- 发布模式差异:本地用Debug模式构建,生产用Release模式,两种模式的依赖处理逻辑不同;或发布时未正确配置参数,导致依赖未完整打包。
- Docker环境差异:Ubuntu上的Docker版本与MacOS存在差异,导致镜像运行时的文件权限、依赖加载逻辑出现问题。
排查方法
- 检查依赖树:在本地项目根目录执行
dotnet list package --include-transitive,定位哪个间接依赖引入了8.0.0版本的目标包,然后通过显式<PackageReference>强制指定该包为7.0.0版本,或更新冲突的第三方包。 - 清理缓存重新构建:在生产服务器执行
docker-compose build --no-cache api,强制重新构建镜像,避免旧缓存带来的依赖异常。 - 优化Dockerfile构建逻辑:
- 将多个
dotnet restore合并为dotnet restore MyApp.sln,一次性还原所有项目依赖,避免重复操作导致的不一致。 - 在
dotnet publish命令中添加--no-restore参数,确保使用已还原的依赖。 - 尝试添加
--self-contained true参数,将所有依赖打包到镜像中,脱离基础镜像的运行时依赖。
- 将多个
- 临时修改容器启动命令:修改Docker Compose中的
entrypoint为["sleep", "3600"],让容器启动后保持运行,再通过docker exec -it <容器ID> bash进入容器,查看/app目录下的依赖文件,检查Microsoft.Extensions.DependencyInjection.Abstractions.dll是否存在及版本。 - 更新基础镜像:执行
docker pull mcr.microsoft.com/dotnet/aspnet:7.0和docker pull mcr.microsoft.com/dotnet/sdk:7.0,确保生产服务器上的基础镜像为最新7.0稳定版,避免镜像更新带来的隐式依赖变化。 - 对比构建产物:将本地
dotnet publish生成的产物与生产镜像中的产物对比,检查依赖文件版本是否一致,排查构建过程中的差异。
内容的提问来源于stack exchange,提问作者Aaron Ullal
相关产品推荐
相关产品推荐

