I'm sure there are lots of people who don't care how debugging a docker container actually works, and who just want to know what buttons to push and in what order. But when you only take this approach, not only are developers left dumber, we become pretty much helpless once something doesn't work.
I have spent several days now without being able to get my project set up so it can be debugged while executing in Docker. This is a service that needs to connect to MSSQL instances that use TLS 1.0, and when we moved from core 2.2 to 3.0 this became an issue - everything would just hang when trying to connect. We can't simply switch on TLS 1.2 as this might break other clients using the same database. But we found a fix by modifying the DockerFile to mess with SSH config files on the runtime image (downgrading minimum TLS requirement from 1.2 to 1.0) and got it working. Then added orchestration support, modified the docker-compose.yml (adding environment varaiables and configuring network), and tried to debug. The debugger attaches, I hit my breakpoints, but now the service reverts to the hanging behavior when trying to connect to the external MSSQL server. In addition, it starts the container in detached mode, where I need it to run in interactive mode.
Nevermind all these details, the point is this: if it was actually documented how this works under the hood, I might have been able to fix it. I know I need to run the remote debugger in the container. I think it can be mounted in as a volume, which is nice since that means it isn't part of the image and you can instead choose when creating the container whether to put the remote debugger in there or not. But the presumably simple act of starting it up in there, and then getting Visual Studio to connect to it automatically (I want to just hit F5 with a Docker debug profile selected, and have it all work) seems to be top secret, because I cannot find any documentation. Google searches turn up lots of "suggestions", but anything more than a month old may be updated the way everything keeps changing, and so far, my frustrating trial-and-error journey hasn't taken me anywhere worth going.
So, please, while docs like these are probably a good idea, supplement it with documentation that explains how it works under the hood, and link to it from doc of the "click here" kind.
⚠Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.
@the-dag -- thank you for your thoughtful feedback. We are looking into this documentation. In addition, you may find some help with your issues here:
You might also consider using the Report a Problem tool to report your concerns.
It looks like more information about how this works behind the scenes could be helpful. In the meantime, some of this has been covered in blogs, so in case its helpful: https://www.paraesthesia.com/archive/2019/06/18/tips-on-container-tools-for-visual-studio/
The remote debugger is indeed volume-mounted in the container when you debug (F5) from Visual Studio. You can look at the docker run command line arguments in the Build pane of the Output Window in VS to see what is being volume-mounted (-v option).
@ghogen Yes, I did notice that. But it mounted three other volumes as well that I don't know what is. I tried to start the container with _-v "C:\Users\me\vsdbg\vs2017u5:/remote_debugger:rw" -p 56567:80 -p 44372:443_, and that seems to work, but it isn't enough to hit F5 and debug. I tried to look at launchsettings.json too, but don't remember exactly how things behaved (some of my attempts encountered various error messages, others did not, but failed to attach the debugger, or attached the debugger, but weirdly didn't seem to use the correct image, because we got the "hanging 4ever when trying to connect to an external MSSQL instance" behavior - https://github.com/dotnet/SqlClient/issues/222 - that we had worked around by changing openssl.cnf files in the container).
I truly don't understand why this happens. To repeat, when adding orchestration support (a docker-compose project) it sets things up so I can run the container and attach to the process by simply hitting F5 (with the docker-compose project as the startup project). My service then fails because it lacks a network and some environment variables I depend on, but that is logical. What is mysterious is when I start the service via my _run.cmd_
`docker container rm -f exampleservice
docker run ^
-it ^
--rm ^
--network net1 ^
--name exampleservice ^
-e ENV1=VALUE ^
-e ENV2=VALUE_ALSO ^
exampleservice:dev`
the thing runs and can connect to MSSQL and get stuff done. But when I change docker-compose.yml to set the same network and environment variables and use the same dockerfile that created the "exampleservice:dev" image, it runs, attaches the debugger, but hangs when the service attempts to connect to MSSQL. This is the same symptom that we had before modifying the openssh settings on the base image (https://github.com/dotnet/SqlClient/issues/222), but it could have a completely different cause.
@the-dag With 16.4 previews, you can now open the Containers window, look at what's going on with the container, and attach to a process. F5 is supposed to work, but now at least if you are starting the container from the command line, you can still attach the debugger.
@the-dag With 16.4 previews, you can now open the Containers window, look at what's going on with the container, and attach to a process. F5 is supposed to work, but now at least if you are starting the container from the command line, you can still attach the debugger.
That sounds awesome! I'll just wait for the RTM then. Thank you for the tip. :)
@the-dag thanks for your feedback. We are constantly working on enriching our documentation and it is definitely on top of our list to explain how the tooling works in the background. In the mean time, I'd be happy to answer any questions you have.
To provide some clarity on volume mounts and debugging, the tooling works in 2 different modes:
Debug mode: where it volume mounts the app, debugger, user secrets folder, nuget folders and the certificates folder (only in case it was an SSL-enabled dotnet core app). This will only run the "base" stage in the Dockerfile, where the app is built on the host machine then mounted and run from the container
Release/non-debug mode: where it runs the whole Dockerfile but doesn't mount the app since it will be copied and built inside the container
The process of running the debugger depends mainly on the type of project:
Dotnet core apps (Linux containers): the tooling downloads "vsdbg" (more info here) and maps it to the container, then it gets called with the debuggee program and arguments (i.e. _dotnet webapp.dll_), and VS can attach to the debugger at that point
Dotnet core apps (Windows containers): the tooling uses "onecoremsvsmon" and maps it to the container, runs it as the entry point and VS connects to it and attaches to the debuggee program. Similar to how you'd setup remote debugging in general
.Net framework apps: the tooling uses "msvsmon" and maps it to the container, runs it as part of the entry point where VS can connect to it and attach to the debuggee program
Hopefully that provided you some insights on volumes and debugging and not added further confusion.
I like to help more on the problem you're having, can you open an issue here https://github.com/microsoft/DockerTools and share an example of what you have in the yaml files (if possible)?
Thanks,
-Hani
We're publishing a detailed article on what's happening during the Container Tools build and debug processes. The changes should go live around 5 pm PST today (11/22/19).
https://docs.microsoft.com/en-us/visualstudio/containers/container-build?view=vs-2019
@the-dag