无法访问 Docker 容器中的 Blazor 应用程序 - 始终在 localhost:5000 上侦听

Can't access Blazor app in Docker container - always listening on localhost:5000

我最近一直在玩 Blazor(服务器端),想在我的 Raspberry Pi 3b+ 上的 Docker 容器中托管第一个应用程序(.Net Core 3.1)。

我正在使用 VS19 自动生成的 Docker 文件,对 Pi 架构和 Docker 文件的位置进行了一些调整:

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

FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster-arm32v7 AS build
WORKDIR /src
COPY ShoppingList.csproj .
RUN dotnet restore "ShoppingList.csproj"
COPY . .
RUN dotnet build "ShoppingList.csproj" -c Release -o /app/build

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

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

当我通过 docker run -p 14050:80 shoppinglist:0.1.21 启动容器时,控制台输出是

warn: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[60]
      Storing keys in a directory '/root/.aspnet/DataProtection-Keys' that may not be persisted outside of the container. Protected data will be unavailable when container is destroyed.
warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35]
      No XML encryptor configured. Key {a885dbd5-0015-480f-8090-d67c55d5850e} may be persisted to storage in unencrypted form.
warn: Microsoft.AspNetCore.Server.Kestrel[0]
      Unable to bind to http://localhost:5000 on the IPv6 loopback interface: 'Cannot assign requested address'.
info: Microsoft.Hosting.Lifetime[0]
      Now listening on: http://localhost:5000
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Production
info: Microsoft.Hosting.Lifetime[0]
      Content root path: /app

但我无法从同一网络中的 PC 访问端口 14050 ("Connection failed") 上的网站。但是,我可以在端口 9000 上访问我的 Portainer - 所以这不是 Pi 的网络地址的问题。

输出也很奇怪,因为它不应该在端口 5000 上侦听。当我进入容器时,ASPNETCORE_URLS 设置为 ASPNETCORE_URLS=http://+:80。通过 docker run -p 14050:5000 shoppinglist:0.1.21 启动容器也无济于事。

这是我的Program.cs。我已尝试使用来自网络的 .UseKestrel().UseUrls("http://*:80") 建议,但这不起作用。 .UseUrls("http://0.0.0.0:80") 也不行。

    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder
                        .UseKestrel()
                        .UseStartup<Startup>();
                        .UseUrls("http://*:80");
                })
                .ConfigureAppConfiguration((context, builder) =>
                {
                    var env = context.HostingEnvironment;
                    builder.Sources.Clear();
                    builder.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
                });
    }

这是我的 launchSettings.json - 是的,我看到了 5000 个端口,但即使我删除或更改所有 applicationUrl 条目,它也会在端口 5000 上侦听。设置 ServicePort env-variable 到 80 也不起作用。

{
  "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iis": {
      "applicationUrl": "http://localhost/ShoppingList",
      "sslPort": 0
    },
    "iisExpress": {
      "applicationUrl": "http://localhost:60279",
      "sslPort": 44389
    }
  },
  "profiles": {
    "IIS Express": {
      "commandName": "Project",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "ShoppingList": {
      "commandName": "Project",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      },
      "applicationUrl": "https://localhost:5001;http://localhost:5000"
    },
    "ShoppingList Prod": {
      "commandName": "Project",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Production"
      },
      "applicationUrl": "https://localhost:5001;http://localhost:5000"
    },
    "Docker": {
      "commandName": "Docker",
      "launchBrowser": true,
      "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}",
      "publishAllPorts": true,
      "useSSL": true
    }
  }
}

我也不知道

warn: Microsoft.AspNetCore.Server.Kestrel[0]
      Unable to bind to http://localhost:5000 on the IPv6 loopback interface: 'Cannot assign requested address'.

部分输出有问题?这在调试时从未发生过。

有谁知道这个 5000 端口来自哪里以及我该如何修复它?

我解决了这个问题。

问题是我的 Program.cs。您不需要主机,您需要一个 WebHost:

using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;

namespace ShoppingList
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IWebHostBuilder CreateHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>()
            .UseUrls("http://*:80")
            .ConfigureAppConfiguration((context, config) =>
            {
                var env = context.HostingEnvironment;
                config.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
            });
    }
}

现在它正在侦听端口 80,我可以从浏览器访问它