Docker:应用程序通过docker-compose工作正常,但如何通过Visual Studio运行并调试?

时间:2017-10-26 08:22:58

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

我有几个项目,他们必须在单独的容器中运行,我有一些共享库也应该是buit。我找到了以下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"]

4 个答案:

答案 0 :(得分:19)

<强> 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

<强>搬运工-compose.override.yml

version: '3'

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

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

哪个不太感兴趣。

<强>搬运工-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
  • 调试的工作目录始终使用/app
  • 设置为com.microsoft.visualstudio.debuggee.workingdirectory
  • 卷装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中给出的上下文获取卷装入量。现在看看你的项目。

<强>搬运工-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中的两行来调试实际工作

FROM microsoft/aspnetcore:2.0 AS base
WORKDIR /app

休息你所做的任何东西都被卷装置扔掉了。所以没有必要为调试做这件事。您可以使用多级构建方法来部署到生产,但不能用于调试。在您的项目中进行这两项更改后,调试开始为我工作

Debugging Working

答案 1 :(得分:0)

我有完全相同的问题构建.Net 2.0 App for Linux。尝试了上面的所有步骤,它没有帮助。对我来说问题是我在csproj文件名和项目目录中使用了空格。

当我删除空格时,它解决了问题。我尝试创建一个名为&#34; WebApplication 1&#34;的Web应用程序。它也失败了,所以看起来像VS工具或它创建的docker文件/组合文件中的错误。

答案 2 :(得分:0)

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

由于被接受的答案中的任何建议都没有对我们起作用,因此我们不得不寻找另一种解决方案。在我们的情况下,我们必须确保

  • Dockerfile中使用的.NET Core 3.0 SDK预览版本与Visual Studio主机上安装的.NET Core 3.0 SDK预览版本相同(我们在Dockerfile中使用了预览4,但已安装了预览5)
  • Docker化项目的Debug配置的输出目录在项目目录内

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

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

答案 3 :(得分:-1)

由于我的项目路径中出现了尖锐的符号(#),因此出现了同样的问题(就像C:\Project\C#\MyProject\这样的C#语言)。

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