为什么aspnet core从Docker内在端口80上启动?

Why does aspnet core start on port 80 from within Docker?

TL;DR: 为什么 aspnet 核心应用程序 运行 在 Docker 图像内部的端口 80 上,但在 [=41] 外部 5000 =] 图片。

详述

我浏览了此处找到的 aspnet 核心/docker 教程: https://docs.microsoft.com/en-us/dotnet/core/docker/building-net-docker-images

页面进行到一半时,我按照规定启动应用程序:

dotnet run

除其他外,这会打印出:

Now Listening on: http://localhost:5000

太棒了。那是我所期望的。本教程的下一件事是从 Docker 图像中启动完全相同的应用程序。

docker build -t aspnetapp .
docker run -it --rm -p 5000:80 --name aspnetcore_sample aspnetapp

这导致

Now listening on: http://[::]:80

等等。哇? 为什么 aspnet 核心应用程序 运行ning 在端口 80 上? 当我直接从机器 运行 时它 运行ning 在端口 5000 上。没有配置文件更改。

我怀疑它与基础 docker 图像有关,但我在 docker 方面还不够熟练,无法找到它。

microsoft/aspnetcore-build 容器建立在 microsoft/aspnetcore 容器之上。 dockerhub page for that 表示:

A note on ports

This image sets the ASPNETCORE_URLS environment variable to http://+:80 which means that if you have not explicity set a URL in your application, via app.UseUrl in your Program.cs for example, then your application will be listening on port 80 inside the container.

所以这是主动将端口设置为 80 的容器。如果需要,您可以通过在 Dockerfile:

中执行此操作来覆盖它

ENV ASPNETCORE_URLS=http://+:5000

此外,值得注意的是,由于您正在使用 docker 命令,无论您是 运行 应用程序,您仍然可以在 http://localhost:5000 访问该应用程序直接或在容器中。

如果您使用的是 .NET Core 2.2 或更高版本,那么您应该使用另一个映像:mcr.microsoft.com/dotnet/core/aspnet :2.2。在那种情况下,指定 ENV ASPNETCORE_URLS=http://+:5000 没有帮助。您仍然可以通过在 Programs.cs 文件中使用 UseUrls("http://*:5000") 强制应用程序监听端口 5000。

没有 docker 文件,您可以设置 docker 容器之外的任何端口。 (.NET 核心 3.1.NET 5.NET 6。 NET 7+) 与 docker args

docker run -it --rm -p 5000:80 -p 5001:443 -e ASPNETCORE_HTTPS_PORT=https://+:5001
           -e ASPNETCORE_URLS=http://+:5000 --name aspnetcore_sample aspnetapp

更多详情:

https://github.com/dotnet/dotnet-docker/blob/17c1eec582e84ba9cbea5641cd9cc13fe1a41c39/samples/run-aspnetcore-https-development.md?plain=1#L85

https://github.com/dotnet/dotnet-docker/blob/5926a01d44bd47b6202ba71e30f9faa08fad1aec/samples/run-in-sdk-container.md?plain=1#L109

Windows 网络堆栈限制对 Windows Docker 容器造成严重影响。Reference Video

docker 运行 -it --rm -p {Host Computer Port}:{Container Port} --name {container name} {image name} docker 运行 -it --rm -p 5000:8090 --name dockerwebapp9172020c dockerwebapp9172020

上面命令的意思是:你的机器端口(5000)映射到容器端口(8090)。这并不意味着应用程序 运行ning 在容器中侦听端口:8090。请参阅下面的 docker 文件了解如何将容器端口映射到应用程序端口。

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-nanoserver-1903 AS base
WORKDIR /app
EXPOSE 8090
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-nanoserver-1903 AS build
WORKDIR /src
COPY ["DockerWebApp/DockerWebApp.csproj", "DockerWebApp/"]
RUN dotnet restore "DockerWebApp/DockerWebApp.csproj"
COPY . .
WORKDIR "/src/DockerWebApp"
RUN dotnet build "DockerWebApp.csproj" -c Release -o /app/build

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

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENV ASPNETCORE_URLS http://*:8090
ENTRYPOINT ["dotnet", "DockerWebApp.dll"]

测试 Windows 网络堆栈限制将不允许 运行 直接跟随命令。

http://localhost:5000

让我们继续第一个解决方法。 Workaround-1 直接打Container。 (在 PowerShell 或命令提示符中的命令下方)

ps c:/>docker inspect f31e8add55af

从最后的“NETWORKS”节点找到容器的 IP 地址,并在浏览器中使用 运行 命令。

http://{container IP}:8090

Workaroud-2 来自 Windows 主机

让我们先找到您的机器 IP 地址。

c:\>ipconfig

找到机器 IP 后,运行 执行以下命令。

http://{Your Machine IP}:5000

因为 5000 映射到容器端口 (8090) 并且 asp.net 核心应用程序也在容器内侦听 8090 端口。

Reference:Windows Containers and Docker: 101