You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.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.Abstractions 7.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 18:46:23