【问题标题】:Docker container works in Visual Studio, but does not when using command lineDocker 容器在 Visual Studio 中工作,但在使用命令行时不工作
【发布时间】:2021-05-10 07:20:45
【问题描述】:

我想要完成的事情

我试图创建的最终结果是 Web API 不暴露给 localhost,但 Web MVC 网站可以与 Web API 通信,解析其结果。

背景

我是 Docker 世界的新手,当我学会了如何并行运行多个容器时,现在我正在尝试使用两个容器之间的网络来回溯我迄今为止所学的一切。

我创建了两个简单的、开箱即用的 .NET 5.0 应用程序:

1. Web API(通过HTTP, 使用端口7070

  • Dockerfile:
FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
WORKDIR /app
EXPOSE 7070

FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src
COPY ["CreatingWebAPI/CreatingWebAPI.csproj", "CreatingWebAPI/"]
RUN dotnet restore "CreatingWebAPI/CreatingWebAPI.csproj"
COPY . .
WORKDIR "/src/CreatingWebAPI"
RUN dotnet build "CreatingWebAPI.csproj" -c Release -o /app/build

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

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENV ASPNETCORE_URLS http://+:7070
ENTRYPOINT ["dotnet", "CreatingWebAPI.dll"]
  • launchSettings.json:
    "Docker": {
      "commandName": "Docker",
      "launchBrowser": true,
      "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger",
      "publishAllPorts": true,
      "useSSL": true
    }
  • 还定义Program.csCreateHostBuilder(string[] args)如下:
webBuilder.UseUrls("http://*:7070").UseStartup<Startup>();

2.显示来自 Web API 的解析表的 Web MVC

我目前面临的问题

通过 Visual Studio 运行 Web API 应用程序(使用 Docker 配置)工作得很好,我可以毫无问题地访问 localhost:&lt;port&gt;/swagger。问题是,在尝试使用 Docker CLI 重现相同的进程时 - 我无法访问 /swagger 接口,无论我尝试访问什么端口或端口。

附上一张 docker CLI 的照片,显示了两个容器的相同细节:

  1. 使用 Visual Studio 生成
  2. 使用docker run --network personal-net --name api -p 50000:7070 creatingwebapi生成

我使用了不同的网络,并尝试一次只创建一个。我什至在这两个上都尝试了docker container inspect 来检查它们之间的任何差异,而没有看到任何不同。那么可能是什么问题呢?

【问题讨论】:

  • 您找到解决方案了吗?我在这里也遇到了同样的问题

标签: visual-studio docker api networking containers


【解决方案1】:

特别是关于您的问题:Swagger 公开您的端点输入、输出、模型,甚至允许任何人对其进行测试(“试用”按钮)。除了开发之外,您不希望在任何环境中出现这种情况。过去同样适用于 wcf 和元数据公开。

webapi 模板遵循此原理,您可以在 startup.cs 文件中找到它:

       if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseSwagger();
            app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "WebApplication2 v1"));
        }

“if (env.IsDevelopment())”只允许在开发环境中使用 swagger,或者比方说:ASPNETCORE_ENVIRONMENT=Development。如果你不指定环境,那么它是空白的,它不是开发,所以 env.isdevelopment() 是假的,所以你不会招摇。

我至少可以想到 3 个选项供您探索和了解正在发生的事情。当他们将环境设置为 DEVELOPMENT 时,这 3 个中的任何一个都应该让您大摇大摆,或者他们删除了这种“仅开发”条件:

  1. 在 Dockerfile 文件中将环境设置为 DEVELOPMENT(请记住 x.development.json 的约定,例如 appsettings)。就像是: ENTRYPOINT ["dotnet", "WebApplication2.dll","--environment=Development"]
  2. 运行 docker 容器,指定环境变量为 Development:docker run -e "ASPNETCORE_ENVIRONMENT=Development" -P --name WebApplication2 webapplication2
  3. 删除 startup.cs 文件中的 if 条件。

我个人会反对第 3 项。Swagger 元数据在较低的环境中很有用(您甚至可以从中创建代理对象),但不应在生产环境中公开。

我认为这里有一个更大的图景:您不希望您的 API 暴露给外部世界。因此,根据您的定义,来自 docker 环境之外的任何人(甚至您)都不能访问 swagger。

我正在考虑如何拒绝外部世界对 api 的访问(希望在这里引发想法):

  1. 仍然大摇大摆:使用防火墙拒绝传入流量到 weabpi 容器的 ip/端口。
  2. 失去访问 API ip/port 的能力:尝试使容器相互通信,认为使容器(web 和 api)相互通信需要它们之间的内部连接,但不一定暴露一个 ipport给主人。 https://www.tutorialworks.com/container-networking/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-19
    • 2021-08-18
    • 2020-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-18
    相关资源
    最近更新 更多