【问题标题】:Docker: applications works fine via docker-compose up, but how to run it via Visual Studio and debug?Docker:应用程序通过 docker-compose up 可以正常工作,但是如何通过 Visual Studio 运行它并进行调试?
【发布时间】:2018-04-07 12:48:07
【问题描述】:

我有几个项目,它们必须在单独的容器中运行,而且我也有一些共享库。我找到了以下article 怎么做。 我将只显示一个项目的 docker 文件,因为它们几乎相同:

FROM microsoft/aspnetcore:2.0 AS base
WORKDIR /app
EXPOSE 80

FROM microsoft/aspnetcore-build:2.0 AS builder
WORKDIR /src
COPY *.sln ./
COPY Web/Web.csproj Web/
RUN dotnet restore
COPY . .
WORKDIR /src/Web
RUN dotnet build -c Debug -o /app

FROM builder AS publish
RUN dotnet publish -c Debug -o /app

FROM base AS production
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "Web.dll"]

所以,如您所见,使用了多阶段构建。如果我使用docker-compose up,那么一切正常。接下来,我尝试通过 Visual Studio 运行它,我在Output 窗口中看到了所有步骤,但最后我收到以下错误:

目标进程退出而没有引发 CoreCLR 启动事件。 确保目标进程配置为使用 .NET Core。这 如果目标进程未在 .NET Core 上运行,则可能会出现这种情况。这 程序“[13] dotnet”已退出,代码为 145 (0x91)。该程序 '' 已退出,代码为 145 (0x91)。

但是现在如何调试应用程序呢?这是github的链接repo

PS。对于 Tarun,VS 生成的默认 docker 文件

FROM microsoft/aspnetcore:2.0
ARG source
WORKDIR /app
EXPOSE 80
COPY ${source:-obj/Docker/publish} .
ENTRYPOINT ["dotnet", "Web.dll"]

【问题讨论】:

  • 这很可能是因为 Visual Studio 有一个额外的 compose 文件被加载。检查他们是否都在您的情况下与运行冲突。应该是docker-compose.ci.build.yml
  • @TarunLalwani。我试图删除...ci.build.yml 文件,但没有任何改变
  • 那么如果你不使用多级dockerfile,它可以工作吗?
  • @TarunLalwani 我没有更改 docker 文件本身。我刚刚删除了 ci dockerfile。此外,我不想更改问题中的 dockerfile,因为我也想在 docker 中构建应用程序。如果我使用 Visual Studio 在您从模板创建 ASP.NET Core 项目时生成的简单 dockerfile,则调试工作正常。
  • 你能把默认的 Dockerfile 也贴出来,比较方便

标签: c# visual-studio docker asp.net-core docker-compose


【解决方案1】:

TL;DR;

所以我安装了 VS 2017 并对此进行了深入研究,以了解这里发生了什么。在查看了您的项目的构建过程后,我在下面找到了

docker-compose -f "C:\Users\tarlabs\Desktop\AspNetCoreMultiProject\docker-compose.yml" -f "C:\Users\tarlabs\Desktop\AspNetCoreMultiProject\docker-compose.override.yml" -f "C:\Users\tarlabs\Desktop\AspNetCoreMultiProject\obj\Docker\docker-compose.vs.debug.g.yml" -p dockercompose15184637154516733497 kill

docker-compose.override.yml

version: '3'

services:
  web:
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
    ports:
      - "80"

  api:
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
    ports:
      - "80"

这不是很有趣。

docker-compose.vs.debug.g.yml

version: '3'

services:
  api:
    image: api:dev
    build:
      args:
        source: obj/Docker/empty/
    environment:
      - DOTNET_USE_POLLING_FILE_WATCHER=1
      - NUGET_FALLBACK_PACKAGES=/root/.nuget/fallbackpackages
    volumes:
      - C:\Users\tarlabs\Desktop\AspNetCoreMultiProject:/app
      - C:\Users\tarlabs\vsdbg:/remote_debugger:ro
      - C:\Users\tarlabs\.nuget\packages\:/root/.nuget/packages:ro
      - C:\Program Files\dotnet\sdk\NuGetFallbackFolder:/root/.nuget/fallbackpackages:ro

    entrypoint: tail -f /dev/null
    labels:
      com.microsoft.visualstudio.debuggee.program: "dotnet"
      com.microsoft.visualstudio.debuggee.arguments: " --additionalProbingPath /root/.nuget/packages --additionalProbingPath /root/.nuget/fallbackpackages  bin/Debug/netcoreapp2.0/Api.dll"
      com.microsoft.visualstudio.debuggee.workingdirectory: "/app"
      com.microsoft.visualstudio.debuggee.killprogram: "/bin/bash -c \"if PID=$$(pidof -x dotnet); then kill $$PID; fi\""

  web:
    image: web:dev
    build:
      args:
        source: obj/Docker/empty/
    environment:
      - DOTNET_USE_POLLING_FILE_WATCHER=1
      - NUGET_FALLBACK_PACKAGES=/root/.nuget/fallbackpackages
    volumes:
      - C:\Users\tarlabs\Desktop\AspNetCoreMultiProject:/app
      - C:\Users\tarlabs\vsdbg:/remote_debugger:ro
      - C:\Users\tarlabs\.nuget\packages\:/root/.nuget/packages:ro
      - C:\Program Files\dotnet\sdk\NuGetFallbackFolder:/root/.nuget/fallbackpackages:ro

    entrypoint: tail -f /dev/null
    labels:
      com.microsoft.visualstudio.debuggee.program: "dotnet"
      com.microsoft.visualstudio.debuggee.arguments: " --additionalProbingPath /root/.nuget/packages --additionalProbingPath /root/.nuget/fallbackpackages  bin/Debug/netcoreapp2.0/Web.dll"
      com.microsoft.visualstudio.debuggee.workingdirectory: "/app"
      com.microsoft.visualstudio.debuggee.killprogram: "/bin/bash -c \"if PID=$$(pidof -x dotnet); then kill $$PID; fi\""

一些有趣的事情

  • 我们定义的ENTRYPOINT 在调试过程中不会产生影响,因为它被VS 用tail -f /dev/null 覆盖
  • com.microsoft.visualstudio.debuggee.arguments 具有路径为bin/Debug/netcoreapp2.0/Web.dll 的值
  • 调试的工作目录总是使用com.microsoft.visualstudio.debuggee.workingdirectory设置为/app
  • 卷装C:\Users\tarlabs\Desktop\AspNetCoreMultiProject:/app

看着卷挂载C:\Users\tarlabs\Desktop\AspNetCoreMultiProject:/app,我就像哇! Dockerfile 中 /app 文件夹中的任何内容都将被该挂载覆盖。因此,无论您是构建文件并将其放入其中还是不做任何事情都不会产生影响。

现在我进入容器并意识到Web.dll 是内部人员/app/Web/bin/Debug/netcoreapp2.0/Web.dll,但调试器预计它位于/app/bin/Debug/netcoreapp2.0/Web.dll。在查看了每个设置之后,我在任何地方都找不到这条路径。

然后我尝试了一个新项目。添加一个支持 Docker 的项目,然后添加另一个支持 Docker 的项目。这给了我一个提示,因为 docker-compose.yml

version: '3'

services:
  webapplication1:
    image: webapplication1
    build:
      context: ./WebApplication1
      dockerfile:Dockerfile

  webapplication2:
    image: webapplication2
    build:
      context: ./../WebApplication2
      dockerfile: Dockerfile

这给了我一个提示,动态docker-compose.vs.debug.g.yml 文件根据docker-compose.yml 中给出的上下文进行卷挂载。现在查看您的项目。

docker-compose.yml

version: '3'

services:
  web:
    image: web
    build:
      context: .
      dockerfile: Web/Dockerfile

  api:
    image:api
    build:
      context: .
      dockerfile: Api/Dockerfile

由于上下文是.,因此卷安装生成为

- C:\Users\tarlabs\Desktop\AspNetCoreMultiProject:/app

为了更正我们将docker-compose.yml更新为

version: '3'

services:
  web:
    image: web
    build:
      context: ./Web
      dockerfile: Dockerfile

  api:
    image:api
    build:
      context: ./Api
      dockerfile: Dockerfile

接下来,我们的 Dockerfile 做了太多被 VS 调试器忽略的事情。因此,您只需要在 Dockerfile 中添加 2 行代码即可进行实际调试

FROM microsoft/aspnetcore:2.0 AS base
WORKDIR /app

Rest 你所做的任何事情都只是被卷安装扔掉了。因此,为了调试而这样做是没有意义的。您可以使用多阶段构建方法部署到生产环境,但不能用于调试。在您的项目中进行这两项更改后,调试开始为我工作

【讨论】:

    【解决方案2】:

    由于我的项目路径中有一个尖锐的符号 (#)(就像在 C# 中...像 C:\Project\C#\MyProject\),所以遇到了同样的问题。

    从路径 (C:\Project\C-sharp\MyProject\) 中删除了尖锐的符号,我很高兴。

    【讨论】:

    • 我不敢相信我花了半天时间来解决这个问题,结果却得到了你不受欢迎的答案,并发现这实际上是我的问题。你让我今天一整天都感觉很好!恭喜!
    【解决方案3】:

    我在为 Linux 构建 .Net 2.0 应用程序时遇到了完全相同的问题。尝试了上述所有步骤,但没有帮助。我的问题是我在 csproj 文件名和项目目录中使用了空格。

    当我删除空格时,它解决了问题。我尝试创建一个名为“WebApplication 1”的 .Net Core 应用程序,但它也失败了,所以看起来像是 VS 工具或它创建的 docker 文件/撰写文件中的一个错误。

    【讨论】:

    • 就我而言(Windows 10 上的 VurtualBox 中的 boot2docker),缺少的部分是与 docker 主机共享相关文件夹。没有它,安装的文件夹在容器中显示为空。一旦我在 VirtualBox 设置(机器设置 -> 共享文件夹 -> 机器文件夹)中设置了这些,它就开始工作了。
    【解决方案4】:

    在尝试向解决方案添加 docker-compose 支持时,我们的 .NET Core 3.0 项目也遇到了类似的情况。尽管 Dockerfiles 和 docker-compose.yml 是根据 MSDN 博文设置的,并且在 PowerShell 中使用 docker-compose 二进制文件按预期工作,但从 Visual Studio 调试 docker-compose 项目总是失败并出现上述错误消息。

    由于已接受答案中的任何建议都不适合我们,因此我们不得不寻找另一种解决方案。在我们的例子中,我们必须确保

    1. Dockerfile 中使用的 .NET Core 3.0 SDK 预览版与 Visual Studio 主机上安装的相同

    我们的 Dockerfile 配置为使用 .NET Core 3.0 预览版 4,而我们已经将开发工作站更新为 .NET Core 预览版 5。将开发工作降级到 .NET Core 预览版 4 或在 Dockerfile 中使用预览版 5 会有所帮助。

    1. docker 化项目的 Debug 配置的输出目录在项目目录中

    如果输出目录在项目目录之外(例如 ....\bin),则 docker 映像中的远程调试器将使用此二进制文件的相对路径启动。但是无论在 docker-compose.yml 中设置哪个上下文,Visual Studio 都会将项目目录作为 /app 目录挂载到容器中。如果输出目录在项目目录之外,则二进制文件在 docker 容器中不可用。

    1. 您的 dockerized 项目的构建说明的位置

    TL;DR:将构建 docker 映像的说明放在 docker-compose.yml 或 docker-compose.override.yml 中

    我们有三个 docker-compose 文件: - docker-compose.yml:网络、服务、图像名称、卷、环境 - docker-compose.override.yml:用于直接访问内部服务的额外暴露端口 - docker-compose.ci-build.yml:构建 Docker 镜像的指令。

    为了部署到测试和 QA 环境,只需使用 docker-compose.yml。开发人员使用 Docker-compose.yml 和 docker-compose.override.yml 在本地启动整个应用程序并访问内部服务。 Docker-compose.yml 和 Docker-compose.ci-build.yml

    因此,构建 docker 映像的说明既不在 docker-compose.yml 中,也不在 docker-compose.override.yml 中。 Visual Studio 似乎忽略了添加到 docker-compose 项目中的所有文件,只处理 docker-compose.yml 和 docker-compose.override.yml。如果没有构建指令,Visual Studio 只会运行 docker-compose up 并且永远不会进入调试状态。

    使用 docker-compose.yml 或 docker-compose.override.yml 中的构建指令,Visual Studio 在 \obj\Docker 上生成额外的 docker-compose 文件:docker-compose.vs.debug.g.yml 和 docker-compose。 vs.debug.partial.g.yml。这些文件包含调试映像的构建说明,您将能够调试您的 dockerized 项目。

    1. docker-compose 和 Dockerfile 中的路径 您还应该知道,更改 docker-compose.yml 中的上下文可能需要更改项目的 Dockerfile。 Dockerfile 中的路径是相对于上下文的,而不是相对于 Dockerfile 的。更改 docker-compose.yml 中的上下文可能会破坏这些相对路径。

    【讨论】:

      猜你喜欢
      • 2020-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-11
      • 1970-01-01
      • 2022-06-20
      • 1970-01-01
      相关资源
      最近更新 更多