.NET Core 应用程序在 Docker 中的 appSettings.json?

24

我正在一个 Docker 容器中运行 .net core 应用程序。这是我的 Docker 文件(仅用于构建开发环境):

FROM microsoft/dotnet:1.0.1-sdk-projectjson 
ENV ASPNET_ENV Development
COPY bin/Debug/netcoreapp1.0/publish/ /root/
EXPOSE 5000/tcp
ENTRYPOINT dotnet /root/AVP.WebApi.dll

我有一个/appSettings.Development.json文件在/publish/文件夹中。如果我构建并运行这个Docker文件,我会遇到一个奇怪的问题,.NET应用程序无法找到需要启动的appsettings(它们在appSettings.Development.json文件中)。

我确认了如果我在Windows命令行中运行dotnet publish/AVP.WebAPI.dll,该应用程序会抛出缺少配置设置的相同异常。但是,如果我进入/publish并运行dotnet AVP.WebAPI.dll,该应用程序将能够正常启动和运行。

有什么想法可以更改我的docker文件,使其能够使用appSettings.Development.json值正常运行应用程序吗?(我还尝试将所有值复制到常规appSettings.json文件中运行应用程序,但没有成功)

我还尝试将COPY命令运行到/而不是/root,并将dotnet AVP.WebApi.dll作为入口点,但结果是该项目无法找到依赖项。

10个回答

22

21

作为对所有人的跟进(我最初在评论中发布了这个),这就是最终解决它的方法:

据我所知,dotnet希望appsettings文件位于它运行的相同目录中。因此,在dockerfile中添加了COPY bin/Debug/netcoreapp1.0/publish/appsettings.json /appsettings.json(此行将appsettings文件复制到/root/下面的目录中,我将发布文件夹复制到了那里)。这时一切都开始工作了。似乎dotnet可执行文件从/root/下面的目录运行,因此以前找不到它,现在既然appsettings在同一个文件夹中,它就很高兴。


4
您可以通过在csproj文件中添加"CopyToPublishDirectory"来解决此问题。具体讨论请参见这里:https://dev59.com/RloU5IYBdhLWcg3wEz-N%C2%B4t-publish-correct-appsettings-env-environmentname-json - shiitake
1
你也可以通过在Program.cs中的ConfigureAppConfiguration中引用appSettings.json文件来解决此问题 - IConfigurationBuilder.AddJsonFile("Path")。 - Tod

5

虽然有些晚了,但我认为我的解决方案能帮到其他人。

步骤1:将appsettings放入"Settings/appsettings.json"文件夹中。 这是我的appsettings.json内容:

{
  "ConnectionString": "Data Source=local;Initial Catalog=mydb;User Id=username;Password=myStr0ngPassword@;"
}

步骤2. 从Asp.net Core编辑代码。

using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;

namespace Repos.Configs
{
    public static class ConfigurationManager
    {
        public static string currentPath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
        public static IConfiguration AppSetting { get; }
        static ConfigurationManager()
        {
            AppSetting = new ConfigurationBuilder()
                    .SetBasePath(currentPath)
                    .AddJsonFile("Settings/appsettings.json") // your path here
                    .Build();
        }
    }
}

并使用AppSetting。

var connectionString = ConfigurationManager.AppSetting["ConnectionString"];

第三步。现在您必须配置您的Dockerfile,在我的情况下,是通过Visual Studio在Linux容器中创建的。

FROM mcr.microsoft.com/dotnet/core/aspnet:3.0-buster-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/core/sdk:3.0-buster AS build
WORKDIR /src
COPY ["Api/Api.csproj", "Api/"]
COPY ["Repos/Repos.csproj", "Repos/"]
COPY ["DataContext/DataContext.csproj", "DataContext/"]
RUN dotnet restore "Api/Api.csproj"
COPY . .
WORKDIR "/src/Api"
RUN dotnet build "Api.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "Api.csproj" -c Release -o /app/publish

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

步骤4. 构建镜像。

docker build -t tagForProject .

步骤5. 映射卷并从镜像中运行容器。

docker run -p 44382:80 --volume c:\Docker\Volumes\MyProjectNetCore:/app/Settings --name nameWillDisplayInDockerDashboard -d tagForProject 

好的,这里有一个问题,因为Docker会把c:\Docker\Volumes\MyProjectNetCore覆盖为/app/Settings。所以,你必须把appseting.json放到c:\Docker\Volumes\MyProjectNetCore中。

如果不这样做,你的应用程序将无法读取appsetting,因为它在docker卷中不存在。

第6步。在docker仪表板中重新启动你的应用程序,并查看它是否工作。


3

我能想到三个问题,可能导致找不到appsettings:

  1. 它们没有在容器的正确文件夹中(您是否复制了发布文件夹,且该文件夹包含appsettings)。
  2. 您没有在StartupClass中定义使用环境的appsettings:appSettings.${Environment}.json
  3. 它在本地工作是因为Windows文件系统不区分大小写,而Linux区分大小写,因此无法找到文件。(检查您的大小写)。

我复制了整个发布文件夹,该文件夹包含appsettings和appsettings开发文件。据我所知,dotnet希望appsettings文件与其运行的目录相同。当我在dockerfile中添加了COPY bin/Debug/netcoreapp1.0/publish/appsettings.json /appsettings.json这一行时(此行将appsettings文件复制到/root/下面的目录中,我已经将发布文件夹复制到该目录下),一切都开始正常工作了。 - Sam Ellis
小提醒一下。我遇到了同样的问题,原因是第三点:大小写敏感。 - vvasch

3

我使用docker-compose和.NET 5,我将它放在我的yaml文件中:

container_name: heroapi
environment:
  - ASPNETCORE_ENVIRONMENT=alpha

使用 appsettings.alpha.json 文件并使其工作


2

对于组合:

environment:
  - ASPNETCORE_ENVIRONMENT=Production

针对 Docker:

ENV ASPNETCORE_ENVIRONMENT: "Production"


2

有一种快速简便的方法可以更新/编辑AppSettings.json文件:

例如,我的AppSettings.json文件:

{
 "GrpcOption": {
    "ServerAddress": "oldurl"
  },
}

现在我可以通过-e命令进行修改了

docker run -e "GrpcOption:ServerAddress=newurl"  [imagename]

1
这应该是被接受的答案,因为它是最少硬编码的方法。 - Kieran Foot

1
我的问题是,在所有这些Docker容器的过程中,我从未以发布模式构建过项目,因此/bin/release/publish中的appsettings.json文件非常旧。

1

我刚刚遇到了这个问题,问题在于该文件默认没有被复制。

通过编辑.csproj文件并添加以下内容来解决此问题:

  <ItemGroup>
    <None Update="appsettings.json">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
  </ItemGroup>

您也可以通过UI完成此操作,方法是在Visual Studio中右键单击appsettings文件,选择属性并将sopy到目录设置为“始终”。


0
我自己也遇到了这个问题,Sam的答案确实解决了它。只是提出一个不同的解决方案,您还可以在Dockerfile中设置WORKDIR /root指令,然后使用ENTRYPOINT dotnet AVP.WebApi.dll,这将在根目录的上下文中调用dotnet。
完整的Dockerfile:
FROM microsoft/dotnet:1.0.1-sdk-projectjson 
ENV ASPNET_ENV Development
COPY bin/Debug/netcoreapp1.0/publish/ /root/
WORKDIR /root
EXPOSE 5000/tcp
ENTRYPOINT dotnet AVP.WebApi.dll

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接