Docker 容器在 Visual Studio 中工作,但在使用命令行时不工作
Docker container works in Visual Studio, but does not when using command line
我想要完成的事情
我尝试创建的最终结果是 Web API 未暴露给本地主机,但 Web MVC 网站可以与 Web API 通信的场景,解析它的结果。
背景
我是 Docker 世界的新手,当我学会如何并排 运行 多个容器时,现在我正在尝试回溯我所学的一切到目前为止在两个容器之间使用网络。
我创建了两个简单的、开箱即用的 .NET 5.0 应用程序:
1. Web API(使用端口 7070
通过 HTTP,
到达)
- Docker文件:
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.cs
CreateHostBuilder(string[] args)
如下:
webBuilder.UseUrls("http://*:7070").UseStartup<Startup>();
2. Web MVC,显示来自 Web API
的已解析 table
我目前面临的问题
运行 Web API 应用程序通过 Visual Studio(使用 Docker
配置)工作正常,我可以毫无问题地访问 localhost:<port>/swagger
.问题是,在尝试使用 Docker CLI 重现相同过程时 - 我无法访问 /swagger
接口,无论我尝试访问什么或什么端口。
附件是 docker CLI 的照片,显示了关于两个容器的相同细节:
- 使用 Visual Studio
生成
- 使用
docker run --network personal-net --name api -p 50000:7070 creatingwebapi
生成
我使用过不同的网络并尝试一次只创建其中一个。我什至在这两个上都尝试了 docker container inspect
来检查它们之间的任何差异,但没有看到任何不同。那可能是什么问题?
特别是关于您的问题: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 个选项供您探索和了解正在发生的事情。这 3 个中的任何一个在将环境设置为 DEVELOPMENT 或删除此“仅开发”条件时都会让您大摇大摆:
- 在 Dockerfile 文件中将环境设置为 DEVELOPMENT(请记住 x.development.json 的约定,例如 appsettings)。就像是:
ENTRYPOINT ["dotnet", "WebApplication2.dll","--environment=Development"]
- 运行 docker容器指定环境变量为Development:
docker run -e "ASPNETCORE_ENVIRONMENT=Development" -P --name WebApplication2 webapplication2
- 删除 startup.cs 文件中的 if 条件。
我个人反对第 3 项。Swagger 元数据在较低环境中很有用(您甚至可以从中创建代理对象),但不应在生产环境中公开。
我认为这里有一个更大的图景:您不希望 API 暴露在外界面前。因此,根据您的定义,docker 环境之外的任何人(即使是您)都不应访问 swagger。
我在想如何拒绝外界对 api 的访问(希望能在这里引发想法):
- 仍然保持招摇:使用防火墙拒绝传入流量到 weabpi 容器的 ip/port。
- 失去到达 API ip/port 的能力:尝试让容器相互通信,让容器(web 和 api)相互通信其他需要它们之间的内部连接,但不一定向主机公开 ipport。 https://www.tutorialworks.com/container-networking/
我想要完成的事情
我尝试创建的最终结果是 Web API 未暴露给本地主机,但 Web MVC 网站可以与 Web API 通信的场景,解析它的结果。
背景
我是 Docker 世界的新手,当我学会如何并排 运行 多个容器时,现在我正在尝试回溯我所学的一切到目前为止在两个容器之间使用网络。
我创建了两个简单的、开箱即用的 .NET 5.0 应用程序:
1. Web API(使用端口 7070
通过 HTTP,
到达)
- Docker文件:
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.cs
CreateHostBuilder(string[] args)
如下:
webBuilder.UseUrls("http://*:7070").UseStartup<Startup>();
2. Web MVC,显示来自 Web API
的已解析 table我目前面临的问题
运行 Web API 应用程序通过 Visual Studio(使用 Docker
配置)工作正常,我可以毫无问题地访问 localhost:<port>/swagger
.问题是,在尝试使用 Docker CLI 重现相同过程时 - 我无法访问 /swagger
接口,无论我尝试访问什么或什么端口。
附件是 docker CLI 的照片,显示了关于两个容器的相同细节:
- 使用 Visual Studio 生成
- 使用
docker run --network personal-net --name api -p 50000:7070 creatingwebapi
生成
我使用过不同的网络并尝试一次只创建其中一个。我什至在这两个上都尝试了 docker container inspect
来检查它们之间的任何差异,但没有看到任何不同。那可能是什么问题?
特别是关于您的问题: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 个选项供您探索和了解正在发生的事情。这 3 个中的任何一个在将环境设置为 DEVELOPMENT 或删除此“仅开发”条件时都会让您大摇大摆:
- 在 Dockerfile 文件中将环境设置为 DEVELOPMENT(请记住 x.development.json 的约定,例如 appsettings)。就像是:
ENTRYPOINT ["dotnet", "WebApplication2.dll","--environment=Development"]
- 运行 docker容器指定环境变量为Development:
docker run -e "ASPNETCORE_ENVIRONMENT=Development" -P --name WebApplication2 webapplication2
- 删除 startup.cs 文件中的 if 条件。
我个人反对第 3 项。Swagger 元数据在较低环境中很有用(您甚至可以从中创建代理对象),但不应在生产环境中公开。
我认为这里有一个更大的图景:您不希望 API 暴露在外界面前。因此,根据您的定义,docker 环境之外的任何人(即使是您)都不应访问 swagger。
我在想如何拒绝外界对 api 的访问(希望能在这里引发想法):
- 仍然保持招摇:使用防火墙拒绝传入流量到 weabpi 容器的 ip/port。
- 失去到达 API ip/port 的能力:尝试让容器相互通信,让容器(web 和 api)相互通信其他需要它们之间的内部连接,但不一定向主机公开 ipport。 https://www.tutorialworks.com/container-networking/