Breakpoints not hit when using docker-compose for asp.net core project

Viewed 2028

I am trying to wrap my head around on how to debug an application, when I am using docker. I found this documentation, which does not yield the expected results: https://code.visualstudio.com/docs/containers/docker-compose

What I did was the following:

  1. dotnet new mvc
  2. Inside VS Code ctrl + shift + p --> Add Docker files to Workspace
  3. modify docker-compose.debug.yml to support SSL
metricdemo:
  image: metricdemo
  build:
    context: .
    dockerfile: Dockerfile
  ports:
    - 80
    - 5000:443
  environment:
    - ASPNETCORE_ENVIRONMENT=Development
    - ASPNETCORE_URLS=http://+:80;https://+:443
    - ASPNETCORE_Kestrel__Certificates__Default__Password=password
    - ASPNETCORE_Kestrel__Certificates__Default__Path=/root/.dotnet/https/aspnetcore-cert.pfx
  volumes:
    - C:\cert\:/root/.dotnet/https
    - ~/.vsdbg:/remote_debugger:rw

the next step was to create the launch configuration, so the debugger can get attached:

{
    "name": "Docker .NET Core Attach (Preview)",
    "type": "docker",
    "request": "attach",
    "platform": "netCore",
    "netCore": {
        "debuggerPath": "/remote_debugger/vsdbg"
    },
    "sourceFileMap": {
        "/src": "${workspaceFolder}"
    }
}

I've tried both combinations with and without the debuggerPath set.

After this I fire up docker-compose using

docker-compose -f "docker-compose.debug.yml" up --build

and then I attach the debugger.

Update The reason debugging does not work is actually the Dockerfile itself:

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
WORKDIR /src
COPY ["MetricDemo.csproj", "./"]
RUN dotnet restore "./MetricDemo.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "MetricDemo.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "MetricDemo.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "MetricDemo.dll"]

Both layers, build and publish are built using Release mode. Setting this to Debug, does the trick. This now begs the question: how can I control this variable from docker-compose, so that I can build debug mode from docker-compose.debug.yml and a release configuration from docker-compose.yml? I don't really want to have 2 docker files for a single project.

2 Answers

I've solved my issue by replacing the hardcoded "Release" configuration, which vs code adds, by an ARG:

FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
WORKDIR /src
COPY ["MetricDemo.csproj", "./"]
RUN dotnet restore "./MetricDemo.csproj"
COPY . .
WORKDIR "/src/."
ARG Mode=Debug
RUN echo "$Mode"
RUN dotnet build "MetricDemo.csproj" -c $Mode -o /app/build

FROM build AS publish
ARG Mode=Debug
RUN echo "$Mode"
RUN dotnet publish "MetricDemo.csproj" -c $Mode -o /app/publish

I am setting the default value to Debug. This will now enable me to simply override this in my docker-compose.yml, when it is supposed to be published:

services:
  metricdemo:
    image: metricdemo
    build:
      context: .
      dockerfile: Dockerfile
      args: 
        - Mode=Release

I had the same problem today, BUT with an existing project migration to docker. My solution was to remove <DebugType>Full</DebugType> out the csproj. That line is a fix for sonar code coverage, so it is possible it breaks that again.

Related