在 Visual Studio 2019 中调试时 Dockerfile 似乎没有运行

rho*_*hof 2 visual-studio docker dockerfile docker-compose

过去几周,我一直在开发一个在 Visual Studio 2019 中使用 C# .NET Core 构建的项目。我启用了 Docker 支持并使用 docker-compose 来启动 2 个容器(它启动了一个 identityserver4 和 webapi)。我已经为两个项目创建了 dockerfiles,并创建了一个用于启动服务堆栈的 docker-compose 文件。

我遇到的问题是,当我在 Visual Studio 调试模式下运行 docker-compose 时,它​​似乎没有运行我的 Dockerfile。在 Dockerfile 的最后一步中,我复制了一些文件并执行命令。这些不会运行。但是,当我docker build在命令行中使用时,它确实会执行那些 Dockerfile 命令。

附上我的 2 个 docker 文件和 docker compose。

Web API Dockerfile:

FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-stretch-slim AS base
WORKDIR /app
EXPOSE 80

FROM mcr.microsoft.com/dotnet/core/sdk:2.2-stretch AS build
WORKDIR /src
COPY ["Api/MyApp.Api.Core/MyApp.Api.Core.csproj", "Api/MyApp.Api.Core/"]
COPY ["Api/MyApp.Api.Base/MyApp.Api.Base.csproj", "Api/MyApp.Api.Base/"]
COPY ["Base/MyApp.Base.Contracts/MyApp.Base.Contracts.csproj", "Base/MyApp.Base.Contracts/"]
COPY ["Base/MyApp.Base.Model/MyApp.Base.Model.csproj", "Base/MyApp.Base.Model/"]
COPY ["Data/MyApp.Data.EntityFramework/MyApp.Data.EntityFramework.csproj", "Data/MyApp.Data.EntityFramework/"]
COPY ["ContactpersoonService.cs/MyApp.Services.csproj", "ContactpersoonService.cs/"]
COPY ["Apps/MyApp.Apps.Settings/MyApp.Apps.Settings.csproj", "Apps/MyApp.Apps.Settings/"]
RUN dotnet restore "Api/MyApp.Api.Core/MyApp.Api.Core.csproj"
COPY . .
WORKDIR "/src/Api/MyApp.Api.Core"
RUN dotnet build "MyApp.Api.Core.csproj" -c Release -o /app

FROM build AS publish
RUN dotnet publish "MyApp.Api.Core.csproj" -c Release -o /app

FROM base AS final
WORKDIR /app
COPY --from=publish /app .
COPY Api/MyApp.Api.Core/Security/Certificates /app/Security/Certificates
RUN mkdir -p /usr/local/share/ca-certificates/identityserver
RUN chmod -R 777 /usr/local/share/ca-certificates/identityserver
RUN cp /app/Security/Certificates/* /usr/local/share/ca-certificates/identityserver
RUN update-ca-certificates
ENTRYPOINT ["dotnet", "MyApp.Api.Core.dll"]
Run Code Online (Sandbox Code Playgroud)

IdentityServer Dockerfile:

FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-stretch-slim AS base
WORKDIR /app
EXPOSE 80

FROM mcr.microsoft.com/dotnet/core/sdk:2.2-stretch AS build
WORKDIR /src
COPY ["Api/MyApp.Api.IdentityServer/MyApp.Api.IdentityServer.csproj", "Api/MyApp.Api.IdentityServer/"]
COPY ["Api/MyApp.Api.Base/MyApp.Api.Base.csproj", "Api/MyApp.Api.Base/"]
COPY ["Base/MyApp.Base.Contracts/MyApp.Base.Contracts.csproj", "Base/MyApp.Base.Contracts/"]
COPY ["Base/MyApp.Base.Model/MyApp.Base.Model.csproj", "Base/MyApp.Base.Model/"]
COPY ["Data/MyApp.Data.EntityFramework/MyApp.Data.EntityFramework.csproj", "Data/MyApp.Data.EntityFramework/"]
COPY ["Apps/MyApp.Apps.Settings/MyApp.Apps.Settings.csproj", "Apps/MyApp.Apps.Settings/"]
RUN dotnet restore "Api/MyApp.Api.IdentityServer/MyApp.Api.IdentityServer.csproj"
COPY . .
WORKDIR "/src/Api/MyApp.Api.IdentityServer"
RUN dotnet build "MyApp.Api.IdentityServer.csproj" -c Release -o /app

FROM build AS publish
RUN dotnet publish "MyApp.Api.IdentityServer.csproj" -c Release -o /app

FROM base AS final
WORKDIR /app
COPY --from=publish /app .
COPY Api/MyApp.Api.Core/Security/Certificates /app/Security/Certificates
RUN mkdir -p /usr/local/share/ca-certificates/identityserver
RUN chmod -R 777 /usr/local/share/ca-certificates/identityserver
RUN cp /app/Security/Certificates/* /usr/local/share/ca-certificates/identityserver
RUN update-ca-certificates
ENTRYPOINT ["dotnet", "MyApp.Api.IdentityServer.dll"]
Run Code Online (Sandbox Code Playgroud)

docker-compose.yaml:

version: '3.4'

services:
  myapp.api.core:
    image: ${DOCKER_REGISTRY-}myappapicore
    build:
      context: .
      dockerfile: Api/MyApp.Api.Core/Dockerfile
    links:
      - myapp.identity.api:identityserver
    ports:
      - "52008:80"
    volumes:
      - "C:/Projects/User/MyApp.Api/Api/MyApp.Api.Core/Security/Certificates/ca.crt:/usr/local/share/ca-certificates/identityserver/identityserver.crt:ro"
    networks:
      app_net:
       ipv4_address: 192.168.1.200

  myapp.identity.api:
    image: ${DOCKER_REGISTRY-}myappapiidentityserver
    build:
      context: .
      dockerfile: Identity/MyApp.Identity.Api/Dockerfile
    ports:
      - "5000:80"
      - "5001:443"
    volumes:
      - "C:/Projects/User/MyApp.Api/Api/MyApp.Api.IdentityServer/Security/Certificates/ca.crt:/usr/local/share/ca-certificates/identityserver/identityserver.crt:ro"
    networks:
      app_net:
       ipv4_address: 192.168.1.201

networks:
  app_net:
    external: true
Run Code Online (Sandbox Code Playgroud)

我正在使用 Visual Studio 2019 (16.3.4)

Myl*_*Rip 5

这显然是设计为 Visual Studio 2019 中的“快速模式”优化。请参阅此处的容器调试文档。

它声明的是“快速模式”是在 VS 2019 中调试容器时的默认行为。在这种模式下,仅根据 Dockerfile 构建多阶段构建的第一阶段(基础)。然后 VS 在主机上处理其余部分,忽略 Dockerfile,并通过使用卷挂载将输出共享到容器。这意味着在 VS 2019 中使用 Debug 配置时,您添加到其他阶段的任何自定义步骤都将被忽略。(给出这种不明显且因此可能令人沮丧的优化的原因是容器中的构建比容器中的构建慢得多本地机器。)请注意,此优化仅在使用 Debug 配置时发生。Release 配置将使用整个 Dockerfile。

您的选择是:

  1. 将您的自定义步骤放在 Dockerfile 的第一个(基本)步骤中。

或者

  1. 通过像这样编辑项目文件来禁用此优化:

    <PropertyGroup>
       <ContainerDevelopmentMode>Regular</ContainerDevelopmentMode>
    </PropertyGroup>
    
    Run Code Online (Sandbox Code Playgroud)

还要记住,如果可能,它会尝试重用以前构建的容器,因此您可能需要执行清理或重建以强制构建创建容器的新版本。

祝你好运!

** 编辑 **

在添加容器编排支持(在本例中为 Docker Compose)后尝试使用 ContainerDevelopmentMode 标志时,似乎存在问题。看到这个问题。在问题讨论中建议可以在 docker-compose.dcproj 文件中使用此标志,但有一个错误(仍未修复)使该方法无法工作。

在我之前的答案中暗示但没有明确说明的第三个选项是:

  1. 将您的解决方案配置从调试切换到发布。

这有效,但在您尝试调试应用程序时显然并不理想。