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

ASP.NET在Docker容器中构建内部文件路径的问题及解决方法

ASP.NET Docker容器中路径解析问题

问题描述

在Docker容器运行ASP.NET应用时,使用Directory.GetCurrentDirectory()和Path.Combine()构建内部文件路径,本地Docker调试正常,但生产环境报错:

Could not find a part of the path '/app/Infrastructure/Migrations'.

代码示例

public Seeder()
{
    _migrationFolderPath = Path.Combine(Directory.GetCurrentDirectory(),
                       "Infrastructure", "Migrations");

    _seedFilePath = Path.Combine(Directory.GetCurrentDirectory(),
                       "Infrastructure", "Seed", "data.csv");
}

尝试过AppContext.BaseDirectory,但本地调试无法正常工作。项目结构包含Infrastructure文件夹,下有Migrations和Seed子目录。

Dockerfile内容

FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
WORKDIR /src
COPY ["Sparkle.Api/Sparkle.Api.csproj", "Sparkle.Api/"]
RUN dotnet restore "Sparkle.Api/Sparkle.Api.csproj"
COPY . .
WORKDIR "/src/Sparkle.Api"
RUN dotnet build "Sparkle.Api.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "Sparkle.Api.csproj" -c Release -o /app/publish /p:UseAppHost=false

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Sparkle.Api.dll"]

解决方案

1. 确保文件被正确发布到容器

先确认Infrastructure下的文件会被包含在发布输出中:

  • 右键项目里的Migrations、Seed文件夹及内部文件,打开属性
  • 将复制到输出目录设置为如果较新则复制或始终复制

这样执行dotnet publish时,这些文件会被同步到/app/publish目录,最终出现在容器的/app路径下。

2. 使用稳定的路径获取方式

放弃Directory.GetCurrentDirectory(),改用程序集目录或AppContext.BaseDirectory:

方式一:通过程序集路径获取

using System.Reflection;

public Seeder()
{
    // 获取当前程序集所在的目录
    var assemblyDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
    
    _migrationFolderPath = Path.Combine(assemblyDir, "Infrastructure", "Migrations");
    _seedFilePath = Path.Combine(assemblyDir, "Infrastructure", "Seed", "data.csv");
}

方式二:使用AppContext.BaseDirectory

public Seeder()
{
    _migrationFolderPath = Path.Combine(AppContext.BaseDirectory, "Infrastructure", "Migrations");
    _seedFilePath = Path.Combine(AppContext.BaseDirectory, "Infrastructure", "Seed", "data.csv");
}

注:AppContext.BaseDirectory默认指向应用程序的基础目录,本地调试和容器环境下都能稳定指向正确路径。

3. 验证容器内文件结构

可以进入容器检查文件是否存在:

# 进入运行中的容器
docker exec -it <容器ID> /bin/bash

# 查看/app目录结构
ls -la /app

确认Infrastructure文件夹是否存在于/app目录下,若不存在,重新检查项目文件的复制设置和Dockerfile的发布步骤。

4. 可选:手动补充Dockerfile复制步骤

如果某些文件未被项目设置包含,可在Dockerfile的final阶段手动复制:

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
# 手动复制未被项目包含的文件(示例)
# COPY --from=build /src/Sparkle.Api/Infrastructure/Migrations ./Infrastructure/Migrations
ENTRYPOINT ["dotnet", "Sparkle.Api.dll"]

内容的提问来源于stack exchange,提问作者Overcode

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 04:35:37