繁体   English   中英

Docker-compose 无法访问 .NET Core

[英]Docker-compose with .NET Core unreachable

我是 Docker 的新手,我正在尝试设置 2 个容器,一个运行 mongoDB,一个运行 Web 应用程序。

问题是我无法通过 localhost:5000 或 0.0.0.0:5000 访问我的 .NET 核心应用程序。

Mongo 运行良好。

这是我的 docker-compose.yml

version: '3'
services:
  web:
    build: .
    ports:
     - "5000:5000"
  mongo:
    build: ../../../docker/wishare-mongo/
    volumes:
     - ../../../docker/wishare-mongo:/data/db
    ports:
     - "27017:27017"

.NET Core 应用程序的 Dockerfile

FROM microsoft/aspnetcore-build:2.0 AS build-env
WORKDIR /app
ENV ASPNETCORE_URLS="http://*:5000"

# Copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore

# Copy everything else and build
COPY . ./
RUN dotnet publish -c Release -o out

# Build runtime image
FROM microsoft/aspnetcore:2.0
WORKDIR /app
COPY --from=build-env /app/out .
EXPOSE 5000
ENTRYPOINT ["dotnet", "Wishare-Integration-Api.dll"]

docker-compose build 和 docker-compose up 运行没有错误,这会导致 web 容器:

web_1 | 托管环境:生产web_1 | 内容根路径:/app web_1 | 现在收听: http://[::]:80 web_1 | 应用程序启动。 按 Ctrl+C 关闭。

这是 docker ps 的结果,端口 5000 应该根据 docker ps 结果导出。

Docker ps 结果

有任何想法吗?

看起来 .NET 在生产中使用端口 80,所以当我更改了 docker 文件并导出端口 80 而不是 5000 并且还在 docker-compose 中将端口 5000 更改为端口 80 时,它会按预期工作。

所以我假设为了在端口 5000 上运行它,它需要在 .NET 端进行一些配置。

问题和解决方案摘要:
默认情况下,ASP.NET Core 只侦听 localhost,而不是任何 IP 地址,通常这是在代码级别或 appSettings.json 或 launchSettings.json: http://localhost:5000 中配置的 您可以轻松地将其更改为“ http://*:5000 ”来解决问题。 (您可以指定您希望应用程序侦听的 IP)

确认:

在具有本地主机的容器中工作:

我们可以进入容器 bash,

docker exec -ti <container name> /bin/bash

通过运行验证

curl -X GET http://localhost:5000

在具有 IP 的容器中不起作用

curl -X GET http://{thecontainer IP}:5000

在使用 localhost 的本地机器上不起作用

在 docker compose 中,甚至映射了 5000:5000。 但是在本地电脑上访问 http://localhost:5000 时不起作用

在有 IP 的本地机器上不起作用

  1. 使用 ipconfig 获取您的本地 ip。 即 192.168.1.123
  2. 运行您的 asp.net 核心应用程序
  3. 使用 IP 而不是 localhost 在浏览器中访问您的应用程序: http://19.2.168.1.123您将看到它不起作用。

为什么,这是浏览器如何路由到 docker 容器中的应用程序?

  1. 您的本地主机(在浏览器中输入)-> 您的本地 IP 192.168.1.123
  2. 您的本地 IP 192.168.1.123 -> 容器 IP:192.168.4.45(根据您的 docker 桌面设置)
  3. 容器 IP:192.168.4.45 -> 容器本地主机
  4. Container localhost -> 运行容器的应用程序。

如果应用程序只侦听本地主机,那么,

第 4 步:工作。

第 3 步不起作用,

第 2 步和第 1 步将不起作用。

因此,解决方案是更改应用程序以确保它同时侦听本地主机和所需的 IP。

这是一个如何解决问题的示例(ASP.NET Core 3.1)。 当然,您可以将这些 URL 放入 appSettings 或其他配置中。

        internal static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .UseContentRoot(Directory.GetCurrentDirectory())
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                    // In order to use Docker Container, we need to use *:5000
                    // to listen all IPs instead of only localhost.
                    // feel free to move these IPs settings into appSettings.json
                    webBuilder.UseUrls("http://*:5000","https://*:5001");
                })
                .UseAutofac()
                .UseSerilog();

注意:如何获取容器IP

docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container_name_or_id

来自 MSDN 的 ServerUrls 解释

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/web-host?view=aspnetcore-5.0#server-urls (您也可以使用环境变量 ASPNETCORE_URLS,而不是配置中的硬编码)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM