GithubHelp home page GithubHelp logo

Debug Container about vscode-docker HOT 22 CLOSED

microsoft avatar microsoft commented on May 18, 2024 2
Debug Container

from vscode-docker.

Comments (22)

galvesribeiro avatar galvesribeiro commented on May 18, 2024 10

Guys I just illustrated the docker-compose as an example. Your approaches work well for a single project, without a solution and that has a single container to attach. The idea is to press F5 and attach a debugger to all services inside docker-compose file.

After multiple try and error, I found a better way that doesn't rely on scripts/hacks to suppress the lack of the feature in VSCode.

This is a sample docker-compose.yml at the solution level:

version: '3.1'

services:
  repository-api:
    image: repository-api:debug
    build:
      context: ./src/QUBIX.Repository.API/bin/PublishOutput/
      dockerfile: Dockerfile.debug
    ports: 
      - "10200:10200"
    environment: 
      - ASPNETCORE_ENVIRONMENT=Development
    volumes: 
      - ./src/QUBIX.Repository.API/bin/PublishOutput/:/app
      - ~/.nuget/packages:/root/.nuget/packages:ro
    depends_on: 
      - repository-silo
  repository-silo:
    image: repository-silo:debug
    build:
      context: ./src/QUBIX.Repository.Silo/bin/PublishOutput/
      dockerfile: Dockerfile.debug
    environment: 
      - QUBIX_REPOSITORY_MBR_CS
    volumes: 
      - ./src/QUBIX.Repository.Silo/bin/PublishOutput/:/app
      - ~/.nuget/packages:/root/.nuget/packages:ro
  repository-reader-silo:
    image: repository-reader-silo:debug
    build:
      context: ./src/QUBIX.Repository.Reader.Silo/bin/PublishOutput/
      dockerfile: Dockerfile.debug
    environment: 
      - QUBIX_REPOSITORY_READER_MBR_CS
      - QUBIX_REPOSITORY_READER_DOCDB_EP
      - QUBIX_REPOSITORY_READER_DOCDB_KEY
    volumes: 
      - ./src/QUBIX.Repository.Reader.Silo/bin/PublishOutput/:/app
      - ~/.nuget/packages:/root/.nuget/packages:ro

This is the Dockerfile.debug:

FROM microsoft/dotnet:1.1-sdk-msbuild
ENV NUGET_XMLDOC_MODE=skip 
ARG CLRDBG_VERSION=VS2015U2
WORKDIR /clrdbg
RUN apt-get update \
    && apt-get install -y --no-install-recommends \
        unzip \
    && rm -rf /var/lib/apt/lists/* \
    && curl -SL https://raw.githubusercontent.com/Microsoft/MIEngine/getclrdbg-release/scripts/GetClrDbg.sh --output GetClrDbg.sh \
    && chmod 700 GetClrDbg.sh \
    && ./GetClrDbg.sh $CLRDBG_VERSION \
    && rm GetClrDbg.sh
WORKDIR /app
ENTRYPOINT ["tail", "-f", "/dev/null"]

Note that I have multiple services in it but none of them has the debugger port open. Note also that the DockerFile.debug basically start the container and the entrypoint just keep it alive without exit. It also download the getclrdbg.sh in order to install the debugger (yes, I think both windows and linux containers for .net core SDK should contain the clrdbg) . A volume is mapped to the project output folder in /app and is passed on docker-compose.

Once in a day, when I start working on the project, I just open a terminal into the solution directory and docker-compose up -d. I don't ever need to turn the container down, unless I need to change something in the container itself like ENV vars, the image, etc. Otherwise, you should have the whole compose project up all the time. (If this is the first time, do a docker-compose build to build the images).

Once you have all the containers up and running, you need to configure your VSCode to get it to debug the containers.

This is my tasks.json:

{
    "version": "0.1.0",
    "isShellCommand": true,
    "command": "dotnet",
    "args":[],
    "tasks": [
        {
            "taskName": "publish",
            "args": [
                "${workspaceRoot}/QUBIX-Repository.sln", "-c", "Debug", "-o", "bin/PublishOutput"
            ],
            "isBuildCommand": true,
            "problemMatcher": "$msCompile"
        }
    ]
}

Note that instead of build, I'm using publish. The reason for that is because .Net Core builds doesn't put all your dependencies at the output folder. So inside the container clrdbg will not be able to find the referenced assemblies when requested.

Now this is my launch.json:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Repository-Silo",
            "type": "coreclr",
            "request": "launch",
            "cwd": "/app",
            "program": "/app/QUBIX.Repository.Silo.dll",
            "sourceFileMap": {
                "/app": "${workspaceRoot}/src/QUBIX.Repository.Silo"
            },
            "pipeTransport": {
                "pipeProgram": "/bin/bash",
                "pipeCwd": "${workspaceRoot}",
                "pipeArgs": [
                    "-c",
                    "docker exec -i qubixrepository_repository-silo_1 /clrdbg/clrdbg --interpreter=mi"
                ]
            }
        },
        {
            "name": "Repository-API",
            "type": "coreclr",
            "request": "launch",
            "cwd": "/app",
            "program": "/app/QUBIX.Repository.API.dll",
            "sourceFileMap": {
                "/app": "${workspaceRoot}/src/QUBIX.Repository.API"
            },
            "pipeTransport": {
                "pipeProgram": "/bin/bash",
                "pipeCwd": "${workspaceRoot}",
                "pipeArgs": [
                    "-c",
                    "docker exec -i qubixrepository_repository-api_1 /clrdbg/clrdbg --interpreter=mi"
                ]
            }
        },
        {
            "name": "Repository-Reader-Silo",
            "type": "coreclr",
            "request": "launch",
            "cwd": "/app",
            "program": "/app/QUBIX.Repository.Reader.Silo.dll",
            "sourceFileMap": {
                "/app": "${workspaceRoot}/src/QUBIX.Repository.Reader.Silo"
            },
            "pipeTransport": {
                "pipeProgram": "/bin/bash",
                "pipeCwd": "${workspaceRoot}",
                "pipeArgs": [
                    "-c",
                    "docker exec -i qubixrepository_repository-reader-silo_1 /clrdbg/clrdbg --interpreter=mi"
                ]
            }
        },
        {
            "name": "Repository-Reader-API",
            "type": "coreclr",
            "request": "launch",
            "cwd": "/app",
            "program": "/app/QUBIX.Repository.Reader.API.dll",
            "sourceFileMap": {
                "/app": "${workspaceRoot}/src/QUBIX.Repository.Reader.API"
            },
            "pipeTransport": {
                "pipeProgram": "/bin/bash",
                "pipeCwd": "${workspaceRoot}",
                "pipeArgs": [
                    "-c",
                    "docker exec -i qubixrepository_repository-reader-api_1 /clrdbg/clrdbg --interpreter=mi"
                ]
            }
        }
    ]
}

Now what is happening here? Remember that our publishOutput is mapped to /app into the container? So, for each service/project that I have at the docker-compose.yml, I have a launch configuration. What this launch configuration does, is to call docker exec into the container for that given service and call clrdbg. That will use it to start the remote debugger inside the container and the application to be debugger (which is mapped in /app)and makes .Net Core debugger on you machine to attach to it. Since the dlls are remotely deployed (inside the debugger), the source map parameters tell the debugger where the source is.

This way, when you press stop in a debugger session, the command that exit is the docker exec which started the remote debugger and the application and not the whole container itself. That makes iteration A LOT faster than keep rebuilding the container every time you press F5.

Note that there is no external script or extension at all. All you need is VSCode, C# extension and Docker installed.

That works perfectly! πŸ’ƒ :shipit:

Now the downside 😞

  1. Note that in the launch configuration I'm using docker exec to target directly into a specific container within the service (for example qubixrepository_repository-reader-api_1 in the last entry).
  2. You are not able to scale your composition to more than one instance and debug multiple instances of the same service.
  3. You are not able to hit F5 and attach the debugger to all services. You have to start one by one from VSCode debugger section. (the compound launch configuration just don't work and even if it does, it does not respect the depends_on which declare the docker-compose dependency chain so one service can start before its dependencies).
  4. Use docker-compose as a pre-launch task, slow down a lot the build process and the debugger experience so I removed it.

The desired experience:

  1. I create a docker-compose.yml file, describe the images and services as usual.
  2. Press F5 to run the project
  3. dotnet build happens at solution level
  4. docker-compose check if there is update, if is not and the services are up, just ignore and don't run it. Otherwise, docker-compose build and docker-compose up are invoked.
  5. docker-compose ps to get all the containers for all the configured projects and attach the debugger to each one of them.
  6. When you stop the debugger on VSCode, you just kill the remote debugger process but the containers are still running.
  7. While the debug session is running, you can attach the debugger for the same project multiple times in different containers (i.e qubixrepository_repository-reader-api_1, qubixrepository_repository-reader-api_2, qubixrepository_repository-reader-api_N) so you can debug distributed application

Does it make sense guys? How can we achieved that experience?

Thanks!

from vscode-docker.

philliphoff avatar philliphoff commented on May 18, 2024 1

#500 added preview support for (single project) ASP.NET .NET Core debugging (a la VS). I'd love to know if this gets you closer to what you want and, more importantly, if not, what else is needed.

from vscode-docker.

lostintangent avatar lostintangent commented on May 18, 2024

@galvesribeiro PRs are always welcome! I'm not too familiar with the VS2017 experience, so any feedback/thoughts you have on how to improve this extension would be awesome.

from vscode-docker.

galvesribeiro avatar galvesribeiro commented on May 18, 2024

Hello @lostintangent, thanks for the promptly reply.

Have a look on this post https://blogs.msdn.microsoft.com/webdev/2016/11/16/new-docker-tools-for-visual-studio/

It show how it work on Visual Studio. Basically you right click a project or solution and add Docker support to it. Once it is added, just hit F5 and all the "magic" happens and you have a debugger attached to your target container. On VS2017 it even support multiple containers which are running on docker-compose scenarios so you can debug a bunch of containers part of same compose file at same time...

from vscode-docker.

chrisdias avatar chrisdias commented on May 18, 2024

For Node, the extension generates a docker-compose.debug.yml file that will open both the site and debugger ports and run node with the debug switch. you could automate the debug process by running docker-compose up on the yml file as a pre launch task and then VS Code should be able to attach to it.

For C#, the same pattern could be used... generate the right task file, docker-compose.debug.yml, and then connecting them in launch.json.

from vscode-docker.

spboyer avatar spboyer commented on May 18, 2024

@lostintangent look at my repo here: https://github.com/spboyer/dockerdebugapp
This has the base images and proper debug compose images to attach the debugger to VS Code. There are changes needed to the extension to generate these files for .NET Core.

from vscode-docker.

chrisdias avatar chrisdias commented on May 18, 2024

Cool!

from vscode-docker.

Shawn-Fan avatar Shawn-Fan commented on May 18, 2024

@galvesribeiro
It's very helpful in debugging multi-services, do you have example code?

from vscode-docker.

galvesribeiro avatar galvesribeiro commented on May 18, 2024

@Shawn-Fan multi-services is something not supported by the debugger out-of-the-box unfortunately. Neither is multi-instance of the same service as well (very useful in truly distributed applications).

If you follow my steps in this issue, you can start all the debug containers from the docker-compose up -d and then run each debugger from the debug section on VS for each service.

I still think MSFT must allow us to attach the debugger to multiple services and multiple instances out-of-the-box. What I did was a hack to workaround the debugger limitation.

from vscode-docker.

Shawn-Fan avatar Shawn-Fan commented on May 18, 2024

@galvesribeiro
Thanks for your help very much. I'll try your way late......
Although VS 2017 for windows works pretty nice, I am trying to use Visual studio code in Mac to work in Docker(Hopefully Visual studio for Mac works well as VS 2017).

from vscode-docker.

galvesribeiro avatar galvesribeiro commented on May 18, 2024

Both VS2017 and VS for Mac have the same limitation regarding Docker debugging experience as VSCode...

from vscode-docker.

ferantivero avatar ferantivero commented on May 18, 2024

first of all thanks to @galvesribeiro for the detailed information he shared here. It was really helpful.

For people who is looking to debug aspnetcore 2.0 from vscode I had to do some minimal tweaks to the Dockerfile + launch.json:

  1. change the FROM to microsoft/aspnetcore-build:1.0-2.0 (because my app, maybe you can just go with 2)
  2. use vsdbg instead of clrdbg, since it seems with the latest C# extensions crl is not supported anymore. For detailed information on this please refer to this Dockerfile.debug
  3. changed a little bit the launch.json because point#2 and also included the preLaunchTask for publish:

Important: everything between <> needs to be filled with data from your app

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "<Just_Another_Name_For_Your_Launch_Conf>",
            "type": "coreclr",
            "request": "launch",
            "preLaunchTask": "publish",
            "cwd": "/app",
            "program": "/app/<Your_AppName_Here>.dll",
            "sourceFileMap": {
                "/app": "${workspaceRoot}/<your_project_folder_here>"
            },
            "pipeTransport": {
                "pipeProgram": "docker",
                "pipeCwd": "${workspaceRoot}",
                "pipeArgs": [
                    "exec -i <your_containername_here>"
                ],
                "quoteArgs": false,
                "debuggerPath": "/vsdbg/vsdbg"
            }
        }
    ]
}

Happy debugging!

from vscode-docker.

mmacneil avatar mmacneil commented on May 18, 2024

@galvesribeiro - great work, thanks for sharing. Do you, by chance have an example Dockerfile from one of your service projects - ie. repository-api

Thanks
Mark

from vscode-docker.

galvesribeiro avatar galvesribeiro commented on May 18, 2024

@mmacneil thanks. The debug image is the one I posted here. The runtime image is essentially an empty image inheriting from a microsoft/dotnet runtime-only image and the entrypoint is dotnet myProject.dll without any fancy stuff in it.

from vscode-docker.

mmacneil avatar mmacneil commented on May 18, 2024

Thank you @galvesribeiro, that makes sense. I was thinking somehow you were merging Dockerfile.debug and the runtime image as I have seen that mentioned elsewhere but I see in this case there are 2 separate containers for debug and runtime.

from vscode-docker.

galvesribeiro avatar galvesribeiro commented on May 18, 2024

@philliphoff was it released to VSCode?

from vscode-docker.

philliphoff avatar philliphoff commented on May 18, 2024

@galvesribeiro Sorry, perhaps I got a little ahead of myself. The PR is merged to master, but it's not yet been released.

from vscode-docker.

galvesribeiro avatar galvesribeiro commented on May 18, 2024

from vscode-docker.

PrashanthCorp avatar PrashanthCorp commented on May 18, 2024

@galvesribeiro , we're closing this bug based on the PR #500. File a new bug if you run into any issues. :-)

from vscode-docker.

galvesribeiro avatar galvesribeiro commented on May 18, 2024

Cool @PrashanthCorp I didn't had time myself to test it as I promised. Did it found its way to the release build of VSCode? Is there are doc/guide on how to proper use it and what should we expect from it?

Thanks!

from vscode-docker.

StephenWeatherford avatar StephenWeatherford commented on May 18, 2024

@galvesribeiro Take a look at https://github.com/Microsoft/vscode-docker#debugging-net-core-preview, thanks!

cc @philhoff

from vscode-docker.

galvesribeiro avatar galvesribeiro commented on May 18, 2024

Thanks @StephenWeatherford

Just saw that... However, it still struggle in a single-container debug :( No compose or kubernetes support...

from vscode-docker.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.