【问题标题】:.Net Core 3.1 app in Docker container Environment Variables not workingDocker容器环境变量中的.Net Core 3.1应用程序不起作用
【发布时间】:2020-08-19 08:39:31
【问题描述】:

我正在尝试在本地 docker 容器中运行我的 .Net Core 3.1 Web API 套件。如果我在 docker run 命令(docker run -e ....)中传递我的环境变量,一切都会正常工作。但是,当我尝试通过 --env-file 传递它们时(作为一个文件,因为会有很多),它的行为很奇怪。当我控制台记录从文件中提取的变量时,它工作正常。但是当我去使用变量时,它的作用是如果它不存在/抛出错误。这个例子恰好被转换为 int,但我看到了与字符串相同的问题。我可以将它们注销,但是当我去使用它们或操纵它们时,就好像它们不存在一样。有人见过这样的吗?

C#

var testPort = Environment.GetEnvironmentVariable("TestPort");

Console.WriteLine("Testing Port: " + testPort);

var testPortInt = Convert.ToInt32(testPort);

Docker 配置文件 (dockerlocal.env)

TestPort="1234"

正在运行 Docker 命令以构建/启动

docker build --no-cache -t telematics-web-api -f Dockerfile .

docker run --name telematics-web-api -p 8080:80 --env-file dockerlocal.env telematics-web-api

Dockerfile

FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build

WORKDIR /build

COPY . .

RUN dotnet restore && dotnet publish -c Release -o /app

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 AS final

WORKDIR app

COPY --from=build /app .

EXPOSE 443

EXPOSE 80

ENTRYPOINT ["dotnet", "Telematics.Web.API.dll"]

输出

Testing Port: "1234"
Unhandled exception. System.FormatException: Input string was not in a correct format.
   at System.Number.ThrowOverflowOrFormatException(ParsingStatus status, TypeCode type)
   at System.Number.ParseInt32(ReadOnlySpan`1 value, NumberStyles styles, NumberFormatInfo info)
   at System.Convert.ToInt32(String value)
   at Fluid.Web.API.Startup.ConfigureServices(IServiceCollection services) in /build/Telematics.Web.API/Startup.cs:line 94
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at Microsoft.AspNetCore.Hosting.ConfigureServicesBuilder.InvokeCore(Object instance, IServiceCollection services)
   at Microsoft.AspNetCore.Hosting.ConfigureServicesBuilder.<>c__DisplayClass9_0.<Invoke>g__Startup|0(IServiceCollection serviceCollection)
   at Microsoft.AspNetCore.Hosting.StartupLoader.ConfigureServicesDelegateBuilder`1.<>c__DisplayClass15_0.<BuildStartupServicesFilterPipeline>g__RunPipeline|0(IServiceCollection services)
   at Microsoft.AspNetCore.Hosting.ConfigureServicesBuilder.Invoke(Object instance, IServiceCollection services)
   at Microsoft.AspNetCore.Hosting.ConfigureServicesBuilder.<>c__DisplayClass8_0.<Build>b__0(IServiceCollection services)
   at Microsoft.AspNetCore.Hosting.StartupLoader.ConfigureServicesDelegateBuilder`1.<>c__DisplayClass14_0.<ConfigureServices>g__ConfigureServicesWithContainerConfiguration|0(IServiceCollection services)
   at Microsoft.AspNetCore.Hosting.ConventionBasedStartup.ConfigureServices(IServiceCollection services)
   at Microsoft.AspNetCore.Hosting.WebHost.EnsureApplicationServices()
   at Microsoft.AspNetCore.Hosting.WebHost.Initialize()
   at Microsoft.AspNetCore.Hosting.WebHostBuilder.Build()
   at Fluid.Web.API.Program.BuildWebHost(String[] args) in /build/Telematics.Web.API/Program.cs:line 24
   at Fluid.Web.API.Program.Main(String[] args) in /build/Telematics.Web.API/Program.cs:line 21

编辑:

字符串也会发生。以下代码引发有关主机为空的错误。但它仍然将 URL 写入输出。当我尝试使用 docker run 的 --env-file 参数时会发生这种情况。如果我使用 -e 参数并在命令行中而不是通过文件传入相同的值,它可以正常工作

C#

var url = Environment.GetEnvironmentVariable("AuthUrl"); 

Console.WriteLine(url); 

HttpRequestMessage request = new 
HttpRequestMessage(HttpMethod.Post, url);

request.Content = new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(body));
request.Content.Headers.Remove("Content-Type");
request.Content.Headers.Add("Content-Type", "application/vnd.api+json");
request.Content.Headers.Add("version", "1.6");

var resp = client.SendAsync(request).GetAwaiter().GetResult();

Docker 配置文件 (dockerlocal.env)

AuthUrl="https://..............."

Docker 命令和 Dockerfile 同上

输出

info: Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker[3]
      Route matched with {action = "Login", controller = "Account"}. Executing controller action with signature Microsoft.AspNetCore.Mvc.IActionResult Login(System.String, System.String) on controller Fluid.Web.API.Controllers.AccountController (Telematics.Web.API).
"https://URLFROMDOCKERCONFIGFILE"
info: Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker[2]
      Executed action Fluid.Web.API.Controllers.AccountController.Login (Telematics.Web.API) in 86.2836ms
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
      Executed endpoint 'Fluid.Web.API.Controllers.AccountController.Login (Telematics.Web.API)'
fail: Microsoft.AspNetCore.Server.Kestrel[13]
      Connection id "0HLVFFOERK3K8", Request id "0HLVFFOERK3K8:00000004": An unhandled exception was thrown by the application.
System.InvalidOperationException: An invalid request URI was provided. The request URI must either be an absolute URI or BaseAddress must be set.
   at System.Net.Http.HttpClient.PrepareRequestMessage(HttpRequestMessage request)
   at System.Net.Http.HttpClient.SendAsync(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.SendAsync(HttpRequestMessage request)
   at Fluid.Web.API.Controllers.AccountController.Login(String userName, String password) in /build/Telematics.Web.API/Controllers/AccountController.cs:line 76

【问题讨论】:

    标签: c# docker asp.net-core environment-variables


    【解决方案1】:

    更改dockerlocal.env的文件内容

    TestPort="1234"
    AuthUrl="https://..............."
    

    TestPort=1234
    AuthUrl=https://...............
    

    一切准备就绪。

    【讨论】:

    • 这并不能解决问题。正如我所说,我还有其他实例,我正在提取一个字符串(连接字符串的主机名)。我可以将字符串回显到屏幕上,但是当我尝试使用它时,它不起作用。如果我使用 -e 参数传递它,它确实可以工作,所以我知道代码本身可以工作。
    • C# - var url = Environment.GetEnvironmentVariable("AuthUrl", EnvironmentVariableTarget.Process); Console.WriteLine(url); HttpRequestMessage 请求 = 新的 HttpRequestMessage(HttpMethod.Post, url); Docker 配置 - AuthUrl="https://................" 抛出关于主机为空的错误。但它仍然将 URL 写入输出。当我尝试使用 docker run 的 --env-file 参数时会发生这种情况。如果我使用 -e 参数并传入相同的值,它会写入输出并且也可以正常工作
    • 更新你的问题,而不是 cmets。它更具可读性:)
    • 但发生异常是因为您尝试使用int.parse 这个"1234" 而不是1234
    • 感谢您的可读性建议,对短视深表歉意!在上面添加了编辑,更容易看出它不仅仅是整数
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-25
    • 2023-04-06
    • 1970-01-01
    • 2021-12-28
    • 2018-12-31
    • 2020-10-10
    • 2017-09-23
    相关资源
    最近更新 更多