Open oleksii-udovychenko opened 7 years ago
The challenge is that we'd need to teach VS debugger to launch the app in the way defined above and then it'd need to figure out which processes to attach. This is something we don't support today.
This is something we don't support today.
Will support this in future? I am working on a large enterprise project that consists of front-end (express + react) and back-end (asp.net webapi services + lots of cloud services). I am trying to migrate it to the docker containers on linux and it is imposible with the current state of tooling.
Are there any way to teach visual studio debugger attach window to connect to docker images and allow developers manually choose processes that they want to debug? As far as I see there is no way of doing this. I also tried to connect to docker containers using SSH but it didn't work for me (maybe I am missing something).
I have the same issue when I set the entrypoint in the compose file, it is always overridden by the entrypoint in docker-compose.vs.debug.g.yml. Is there a way to tell the tooling not to override this or some way defining which compose files that the tooling uses when building / starting? Right now I can't use the tooling since I need the ability to set the entrypoint during development.
Is there any workaround available? I have a case where I have to run some 3rd party software in the project container. I am able to download and install it in the docker file, but I am unable to run its services on container startup in any way. It just executes my project and ignores whatever I've configured as CMD or ENTRYPOINT.
Same problem.
I have simple .NET Core console app which expects some args.
But this .yml files just overrides entrypoint and it seems specifying command
does not work too (@dazhao-msft correct me if I wrong).
I found kind of workaround here: https://stackoverflow.com/a/40730210/644496 In short, we have to set environment variables in docker compose and read it at the start:
docker-compose.yml
version: '3'
services:
app:
environment:
arg1: 'value1'
arg2: 123
Program code:
class Program
{
static void Main(string[] args)
{
var arg1 = Environment.GetEnvironmentVariables()["org"].ToString();
var arg2 = Convert.ToInt32(Environment.GetEnvironmentVariables()["arg3"]);
}
}}
@oleksii-udovychenko Did you find a working workaround?
I'm using a custom entrypoint.sh
to do some adjustments in the hosts file of my docker container (at runtime), so i need this entrypoint too.
@JoostvdB94 I don't use visual studio for building and running containerised projects. I just run them through docker-compose from the console and then attach debugger to one of the containers.
@oleksii-udovychenko do you have any pointers for attaching the debugger with Visual Studio? It's easy as with Visual Studio Code, eg:
"pipeTransport":
{
"pipeProgram": "docker",
"pipeCwd": "${workspaceRoot}",
"pipeArgs": ["exec", "-i", "foo"],
"debuggerPath": "/opt/vsdbg/vsdbg",
"quoteArgs": false
}
Just trying to figure out how to do it with Visual Studio for my Windows buddies (I'm predominantly a Linux dev).
@brad-jones , you should be able to create a file named "docker-compose.vs.debug.yml and add this to the docker-compose project, overriding the entrypoint as necessary.. You can start by grabbing the
@dbreshears , I have added a docker-compose.vs.debug.yml file in my docker-compose project:
<ItemGroup>
<None Include="docker-compose.override.yml">
<DependentUpon>docker-compose.yml</DependentUpon>
</None>
<None Include="docker-compose.vs.debug.yml">
<DependentUpon>docker-compose.yml</DependentUpon>
</None>
<None Include="docker-compose.yml" />
<None Include=".dockerignore" />
</ItemGroup>
Its content is based on the \obj\Docker\docker-compose.vs.debug.g.yml file you mentioned. The only difference is the entrypoint property, which I have edited manually.
Still, the issue persists: when debugging with Docker, VS uses the \obj\Docker\docker-compose.vs.debug.g.yml file which is the same as before (i.e. does not take into account the entrypoint property that I manually edited).
Am I doing something wrong?
That certainly looks correct. Can you ensure your startup project is the docker-compose project. In 15.8 we added a single project docker experience, when I unloaded and reloaded docker-compose project when testing this just now, it gets reset to my WebApplication and therefore just does docker run in stead of compose. Also, are you on "Debug" solution config in VS when you F5? Can you share your build output. You should see something like this where the last "-f" argument to compose is docker-compose.vs.debug.yml
2>docker-compose -f "C:\Users\devinb\source\repos\WebApplication3\docker-compose.yml" -f "C:\Users\devinb\source\repos\WebApplication3\docker-compose.override.yml" -f "C:\Users\devinb\source\repos\WebApplication3\obj\Docker\docker-compose.vs.debug.g.yml" -f "C:\Users\devinb\source\repos\WebApplication3\docker-compose.vs.debug.yml" -p dockercompose14141838616008167745 --no-ansi config
I met the similar error, I use the visual studio docker tools, can add some argument to the ENTRYPOINT like this: ENTRYPOINT ["dotnet", "MyApp.dll", "-e", "CONFIG_"]
But when I start to debug, the arguments I add is missing
So the entrypoint
is replaced by the docker-compose.vs.debug.g.yml
to tail -f /dev/null
, it means when I launch by docker-compose in visual studio, it actually not run on docker at all?
@watsonsong When we launch the container in VS, we use that "tail -f /dev/null" command as a way to keep the container alive indefinitely. The app really is running in the container, but it is done via a "docker exec" call rather than the entrypoint. In the case of F5 (debug), we docker exec VSDBG and instruct it to run the app; in the case of Ctrl+F5 (launch w/o debug), we docker exec the app directly.
@bwateratmsft So is there a way I can modity the docker-compose.vs.debug.yml and edit the command line argument for my app?
@haniamr Do you know of a way to do that?
I have the same issue. I'm trying to run a script for my entry point that does a kinit
for a Kerberos ticket before doing the dotnet
command. This works fine if I docker run
the image manually without overriding the entry point, but works not at all with the command that VS wants to run. With VS the app runs but the kinit does not, so whatever tail -f /dev/null
magic is happening, it must be running the app directly and not the as-configured entry point in the Dockerfile.
@oleksii-udovychenko How do you "attach debugger to one of the containers"?
So I managed to get this working. It's kind of annoying having to manage yet another docker override file just for VS, but it's at least a solution. The reason this is required is because VS starts your containers at the moment you open the solution (and cleans them up when you close). It isn't until you run or debug the solution that VS will try to start your app in the container using docker exec. It uses the settings configured in the following labels of the docker-compose.vs.{env}.g.yml file in order to start your app:
com.microsoft.visualstudio.debuggee.program
com.microsoft.visualstudio.debuggee.arguments
com.microsoft.visualstudio.debuggee.workingdirectory
com.microsoft.visualstudio.debuggee.killprogram
You simply need to set these labels to the proper values to tell the debugger how to start your app in the container. To do this, you need to create a new file next to your docker-compose.yml called docker-compose.vs.debug.yml
with the following contents:
Here's an example:
version: '3.4'
services:
my-service:
labels:
com.microsoft.visualstudio.debuggee.program: "/bin/sh"
com.microsoft.visualstudio.debuggee.arguments: "-c your_command --with-args"
com.microsoft.visualstudio.debuggee.workingdirectory: "/app"
com.microsoft.visualstudio.debuggee.killprogram: "/bin/sh -c \"if PID=$$(pidof your_command); then kill $$PID; fi\""
Note that you cannot use environment variables in the above labels. They for whatever reason always resolve to empty.
Also, the easiest way to create the docker-compose.vs.debug.yml
file is to copy the existing docker-compose.vs.debug.g.yml
file (from /obj/Docker
) and rename it to remove the .g
.
Hope that helps, and is clear enough to get some people unstuck.
@mikesigs
Thanks for your post. Recently in my free time I started to learn docker and one of tutorials I did was https://docs.microsoft.com/en-us/visualstudio/containers/tutorial-multicontainer?view=vs-2019. After I complete tutorial I wanted to add docker watch
but I didn't know how to force VS to respect my ENTRYPOINT
from Dockerfile.
I finally managed to combine dotnet watch
+ VS debugger
+ docker-compose
. As mentioned earlier, docker-compose.vs.debug.yml must be override and placed in the same folder where docker-compose.yml is located.
version: '3.4'
services:
dockertest-webapi:
labels:
com.microsoft.visualstudio.debuggee.program: "dotnet"
com.microsoft.visualstudio.debuggee.arguments: "--additionalProbingPath /root/.nuget/packages --additionalProbingPath /root/.nuget/fallbackpackages \"/app/bin/local/Debug/netcoreapp3.1/DockerTest-WebApi.dll\" & dotnet watch -p /code/app/api/DockerTest-WebApi run --urls=\"http://+:80;https://+:443\""
com.microsoft.visualstudio.debuggee.workingdirectory: "/code/app/api/DockerTest-WebApi"
com.microsoft.visualstudio.debuggee.killprogram: "/bin/sh -c \"if PID=$$(pidof your_command); then kill $$PID; fi\""
dockertest-webfrontend:
labels:
com.microsoft.visualstudio.debuggee.program: "dotnet"
com.microsoft.visualstudio.debuggee.arguments: " --additionalProbingPath /root/.nuget/packages --additionalProbingPath /root/.nuget/fallbackpackages \"/app/bin/local/Debug/netcoreapp3.1/DockerTest-WebFrontend.dll\" & dotnet watch -p /code/app/web/DockerTest-WebFrontend run --urls=\"http://+:80;https://+:443\""
com.microsoft.visualstudio.debuggee.workingdirectory: "/code/app/web/DockerTest-WebFrontend"
com.microsoft.visualstudio.debuggee.killprogram: "/bin/sh -c \"if PID=$$(pidof your_command); then kill $$PID; fi\""
More information about docker-compose.vs.debug.yml can be found here: https://docs.microsoft.com/en-us/visualstudio/containers/docker-compose-properties?view=vs-2019
Hello,
I'm happy to find this issue, so I know I'm not alone, but obviously in a very exclusive club. ;)
I use Docker and docker-compose to start several API projects in one Visual Studio solution.
Since the Docker parameter depends_on
does not wait for those other containers/services to start healthy it is hard to control the order of container execution.
I could override the entrypoint
of one container with a script to check the existence/running of his dependencies.
Docker officially recommends using this bash script "https://github.com/vishnubob/wait-for-it"
Problem (1): It is a bash script, how could I use it in a windows container based on mcr.microsoft.com/dotnet/core/aspnet:3.1
... So I wrote an old-school batch file to curl/ping
the url of the dependent service.
Problem (2): this issue, open since 2017 (!)
My question: What is the best way in Visual Studio (Debug Mode with docker-compose) to ensure a dependent container is running before starting the actual container ?
... and is there any progress on this issue, since I cannot believe I am the only one who wants control over the entrypoint
in a more easy way.
Thanks, Sascha
Commenting just to raise more awareness to this. I have the same issue.
In my case, I am trying to run two Linux-based containers with Compose: an ASP.NET Core app and a MySQL database that the app depends on. The former needs to wait for the latter to start up.
To the question on starting dependent containers, we added a new feature (https://devblogs.microsoft.com/visualstudio/visual-studio-2019-v16-10-preview-2/#run-launch-services-defined-in-your-compose-files) which allows creating a profile to start specific set of services in a compose project. Using this feature, a profile can be created to start just the dependent services and another profile that starts the main development services. Ctrl+F5 on depended service profile will start the dependent service and then use the other profile for debugging the main services.
I'm pretty new at this, so I hope you'll forgive if I have some misunderstandings. But after a few hours working on why my docker setup in Visual Studio was behaving differently than my commandline docker setup, I have a few thoughts, from a newbie's perspective:
Violation of Docker Intuition: As a docker newbie, I expect a container that is in a running state to be running my application logic, 1 running container == 1 running process, which I think is a docker principle. Instead sometimes container is just waiting for the debugger to start(especially if I stopped debugging recently).
If I am not debugging actively, but the container is online--I expect my integration tests/api calls from other projects to interact with the application process inside the running container--but because I'm not debugging--the application isn't running, causing misleading test failures until I realize container running != process running.
Inconsistency with Production: The debugging approach introduces deviations from the production runtime behavior. This divergence can result in "it works on my machine" scenarios, contrary to one of Docker's key benefits: consistency across environments.
Lack of Transparency(aka maybe I'm just ignorant): The automated adjustments, such as overriding the entrypoint, lack transparency in my view. Developers familiar with Docker's paradigms expect certain behaviors that Visual Studio's tooling unexpectedly modifies.
I eventually found out what was going wrong in my setup from this page:
https://learn.microsoft.com/en-us/visualstudio/containers/container-build?view=vs-2022#container-entry-point
The entry point is tail -f /dev/null, which is an infinite wait to keep the container running. When the app is launched through the debugger, it is the debugger that is responsible to run the app (that is, dotnet webapp.dll). If launched without debugging, the tooling runs a docker exec -i {containerId} dotnet webapp.dll to run the app.
And this ticket. But nothing in Visual Studio warned me about what I see as unusual(for docker) behavior.
In essence, while Visual Studio aims to provide a seamless debugging experience, it compromises the foundational principles of containerization. A debugging toolset that both respects Docker's best practices and offers a smooth developer experience would be much appreciated. I understand this is probably more complicated than I think it is, but just wanted to add my story to this issue, in case it moves the needle priority-wise for anyone.
Introduction
I've tried to launch supervisord in a container to run both
webpack-dev-server
and .NET Core Web App at the same time (for development purposes).I've created the following
Dockerfile
:and the following
supervisord.conf
file:When I hit F5, I see that
supervisor
doesn't start, sofrontend
andbackend
apps shouldn't start. The weird thing is that my App.dll starts successfuly. When I startedsupervisor
manually from the container itself, I noticed thatbackend
(which is my App.dll) can't be started (because it is already running), butfrontend
works fine:After few more tries I realized that VS2017 starts my app behind the scenes and ignores my ENTRYPOINT because
docker-compose.vs.debug.yml
overrides the ENTRYPOINT with the following command:Changing
entrypoint
indocker-compose.vs.debug.yml
doesn't help, it seems thattail -f /dev/null
command is required.Problem
The problem is that I can't find where and how my app starts. Also, it would be great to know a way to change default VS2017 behavior, so I can stop VS2017 from launching my app and launch
supervisord
instead.Maybe I am missing something?
I was able to isolate and reproduce this issue(?).
Steps to reproduce
Dockerfile
and change ENTRYPOINT to something that should cause an error.EXPECTED RESULT: Console app doesn't start.
ACTUAL RESULT: