Docker: applications works fine via docker-compose up, but how to run it via Visual Studio and debug?
TL;DR;
So I installed VS 2017 and had a dig at this to understand what goes on here. After looking at the build process for your project I found below
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"
Which is not much of interest.
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\""
Few interesting things
- The
ENTRYPOINT
we define won't make a difference during debugging as it overridden by VS withtail -f /dev/null
- The
com.microsoft.visualstudio.debuggee.arguments
has a value with pathbin/Debug/netcoreapp2.0/Web.dll
- The working directory for debugging is always set to
/app
usingcom.microsoft.visualstudio.debuggee.workingdirectory
- Volume mount
C:\Users\tarlabs\Desktop\AspNetCoreMultiProject:/app
Looking at Volume mount C:\Users\tarlabs\Desktop\AspNetCoreMultiProject:/app
, I was like Wow! Anything that you have in your /app
folder in your Dockerfile, will be just overridden by that mount. So whether you build and put the files inside that or you don't do anything won't make a difference.
Now I went inside the container and realized that the Web.dll
is insider /app/Web/bin/Debug/netcoreapp2.0/Web.dll
but the debugger is expecting it to be on /app/bin/Debug/netcoreapp2.0/Web.dll
. After looking in every setting I could not find this path anywhere.
Then I played around with a new project. Adding one project with Docker support and later adding another project with docker support. This gave me a hint as the docker-compose.yml
was
version: '3'
services:
webapplication1:
image: webapplication1
build:
context: ./WebApplication1
dockerfile:Dockerfile
webapplication2:
image: webapplication2
build:
context: ./../WebApplication2
dockerfile: Dockerfile
This gave me a hint that the dynamic docker-compose.vs.debug.g.yml
file takes the volume mount based on the context given in your docker-compose.yml
. Now looking at your project.
docker-compose.yml
version: '3'
services:
web:
image: web
build:
context: .
dockerfile: Web/Dockerfile
api:
image:api
build:
context: .
dockerfile: Api/Dockerfile
Since the context is .
the Volume mount is generated as
- C:\Users\tarlabs\Desktop\AspNetCoreMultiProject:/app
To correct that we update our docker-compose.yml
to
version: '3'
services:
web:
image: web
build:
context: ./Web
dockerfile: Dockerfile
api:
image:api
build:
context: ./Api
dockerfile: Dockerfile
Next our Dockerfile was doing too many things which VS debugger kind of just ignores. So you just needs 2 lines in your Dockerfile
for debugging to actually work
FROM microsoft/aspnetcore:2.0 AS base
WORKDIR /app
Rest anything that you did was just thrown away by the volume mount. So no point in doing that for debugging. You can use multistage build approach for deploying to production but not for debugging. After making those two changes in your project debugging started working for me
Had the same issue because of a Sharp Symbol (#
) in my project path (Like in C#... like C:\Project\C#\MyProject\
).
Removed the sharp symbol from the path (C:\Project\C-sharp\MyProject\
) and I was good to go.