Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

debugging .NET containers fails out of the box #759

Closed
jldeen opened this issue Jan 27, 2019 · 11 comments
Closed

debugging .NET containers fails out of the box #759

jldeen opened this issue Jan 27, 2019 · 11 comments
Assignees

Comments

@jldeen
Copy link

jldeen commented Jan 27, 2019

Tested out debugging dotnet core Linux containers on 2 different macOS systems, one with a completely clean VS Code installation.

VS Code Version: 1.30.2 (1.30.2)
Docker Version: 2.0.1.0 (30090)
.NET Core SDK: 2.2.103
macOS: 10.14.3 Beta (18D39a)

Steps to reproduce

  1. Using Docker extension, added Docker files to the work space
  2. Followed instructions on Extension page to for Debugging .NET Core (Preview)
  3. Confirmed running .NET Core SDK 2.2.103
  4. Confirmed C# is installed
  5. Confirmed /usr/local/share/dotnet/sdk/NuGetFallbackFolder is added as a shared folder in Docker preferences
  6. Switch to the debugging tab.
  7. Select Add configuration...
  8. Select Docker: Launch .NET Core (Preview)

Encountered error below:

Error:

warn: Microsoft.AspNetCore.Server.Kestrel[0]
      Unable to bind to http://localhost:5000 on the IPv6 loopback interface: 'Error -99 EADDRNOTAVAIL address not available'.
Hosting environment: Production
Content root path: /app
Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.
The thread 42 has exited with code 0 (0x0).

When I navigate to localhost:5000 nothing is serving. I noticed the VS Code created Dockerfile is not exposing any port. I added two lines and still could not get the debugging to work.

ENV PORT 80
EXPOSE 80

As such I have not been able to test setting breakpoints and perform live debugging of my .NET Core container.

I did do further debugging and noticed there does not appear to be a port published for the container run with the debugger:

CONTAINER ID        IMAGE               COMMAND               CREATED             STATUS              PORTS               NAMES
26d7f0448713        e317532d9dd7        "tail -f /dev/null"   2 minutes ago       Up 2 minutes                            WebApplication-dev
@philliphoff
Copy link
Member

@jldeen Can you describe the type of project/workspace to which you're adding Docker files and debugging? What version of the vscode-docker extension are you running? Is this a brand-new application or an existing one? If the latter, can you debug an application in Docker created via dotnet new web (just as a test)?

I'm not seeing the missing EXPOSE in the Dockerfile, nor the Kestrel warning in the debugging output.

@jldeen
Copy link
Author

jldeen commented Jan 28, 2019

@philliphoff I used a public project in the Azure Draft example-dotnet repo - it's a simple demo project. https://github.com/Azure/draft/tree/master/examples/example-dotnet. Version of vscode-docker is 0.5.1 - everything is a clean install as of the opening of this issue.

Here is the Dockerfile that is produced:

FROM microsoft/dotnet:2.2-runtime AS base
WORKDIR /app

FROM microsoft/dotnet:2.2-sdk AS build
WORKDIR /src
COPY ["WebApplication.csproj", "./"]
RUN dotnet restore "./WebApplication.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "WebApplication.csproj" -c Release -o /app

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

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

As you can see, there is no EXPOSE in any stage, even final

@philliphoff
Copy link
Member

How strange. When I generate the Docker files for that project, either as an individual workspace or as part of the larger repo workspace, I get a Dockerfile that includes the EXPOSE line for the base target, and debugging works as expected. (When the workspace is the larger repo folder, I do have to adjust the appFolder and dockerfile properties of the debug configuration, but otherwise seems to work.)

I noticed that the repo's current version of the project targets netcoreapp2.0, so my generated Dockerfile uses microsoft/aspnetcore:2.0 as the base image. In your example Dockerfile, the base image is microsoft/dotnet:2.2-runtime (as if it were targeting 2.2). However, even when I retarget the project to netcoreapp2.2, the generated Dockerfile now uses the microsoft/dotnet:2.2-runtime base image, but still includes the EXPOSE line and still debugs as expected.

@jldeen
Copy link
Author

jldeen commented Jan 29, 2019

I'm not sure what I'm doing wrong then, I have tried this on two different computers with that same project.

I tried with a complete fresh dotnet application (also on 2 computers) dotnet new web and this is the output of the Dockerfile I got:

FROM microsoft/dotnet:2.2-runtime AS base
WORKDIR /app

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

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

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

So still no EXPOSE as you're seeing.

dotnet --version reveals 2.2.103 on one computer and 2.2.100-preview1-009349 on another. Both macOS.

.NET Core Launch (web) works fine, launches a browser at localhost:5000 and allows me to debug, but when I try with the Docker: Launch .NET Core (Preview) debugger I get the same error and behavior reported above. Also, as mentioned, docker ps reports a running container, but there are no ports exposed.

@philliphoff
Copy link
Member

Huh, that's so odd. When you're adding the Dockerfile, are you even prompted to enter a port (after selecting the project type (ASP.NET Core) and OS (Linux))? Usually port 80 is the default; I'm not sure where port 5000 is coming from.

@jldeen
Copy link
Author

jldeen commented Jan 29, 2019

I am not prompted to enter a port for .NET Core Console, only for Node.js apps. I recorded a short 5 min video of what I'm seeing. I'm not using my normal video editing system at the moment so the video says "Demo mode" but you will get the gist.

There are two demos - the first one is the dotnet new web test I did and the second is the example-dotnet Draft repo I first reported this issue with. Both demos show how I am not asked for which port. The second demo starts at 2:41. The second video also inlcludes the .NET Core Launch (web) working, which, funny enough, serves on localhost:5000.

Edit I just realized, you said project type as ASP.NET Core. I have been selecting .NET Core Console... Coming from the linux world, I thought ASP.NET core was for Windows-based containers, not an option of Windows or linux. It's also confusing because the debugger refers to the project as .NET Core. I am testing now with ASP.NET Core

@jldeen
Copy link
Author

jldeen commented Jan 29, 2019

Ok, using ASP.NET Core as the project type for the Add Dockerfiles to the Workspace part DOES work, but now I suggest updating the documentation or project type in the extension. The first time I heard I was to use ASP.NET Core was through this issue. In fact, the documentation refers to the app framework at least 8 times as ".NET Core"; ASP.NET Core is not mentioned once.

Also, adding clarity to what the difference between ASP.NET Core and .NET Core Console is/does for the Docker extension might be helpful.

@philliphoff
Copy link
Member

@jldeen Ah, ok, so I see the same issues you are when using the .Net Core Console generated Dockerfile. In order to make that work, I had to add an EXPOSE 5000 line to the Dockerfile and add UseUrls("http://*:5000") to the WebHostBuilder configuration.

        public static void Main(string[] args)
        {
            var host = new WebHostBuilder()
                .UseUrls("http://*:5000")
                .UseKestrel()
                .UseContentRoot(Directory.GetCurrentDirectory())
                .UseIISIntegration()
                .UseStartup<Startup>()
                .Build();

            host.Run();
        }

After that, debugging works as expected.

So I've compiled a few notes:

  • The .NET Core Console Dockerfile uses the microsoft/dotnet:2.0-runtime base image which is optimized for general .NET Core applications and, as such, doesn't set the typical ASP.NET Core environment variables, which therefore require UseUrls("http://*:5000") to ensure Kestrel is binding properly to the container's ports. The ASP.NET Core Dockerfile uses the microsoft/aspnetcore:2.0 base image which, obviously, explicitly targets ASP.NET Core applications and presets some configuration.
  • The .NET Core Console Dockerfile doesn't prompt for a port to expose in the Dockerfile as, again, it's optimized for general .NET Core applications and doesn't make assumptions about whether/how the application accepts incoming connections. The ASP.NET Core Dockerfile, again targeting web applications, assumes and prompts for at least one exposed port.
  • The debugger targets .NET Core in general and not a particular type of .NET Core application; there's an assumption that the Dockerfile is set up to match the type of application.
  • The term ASP.NET Core is agnostic to the underlying platform (i.e. Linux vs. Windows). (In fact, the VS Code .NET Core debugger can only be used in Linux containers.) . That said, one can make an argument that an ASP.NET Core application is a console application, in particular, when running in Linux containers. (In Windows containers it can be started via the console or hosted within IIS.) So, I can see how that could be confusing and better documentation could help.

I also noticed that we don't yet support the ability to set/override the URL browsed to for an arbitrary container. (Currently the debugger detects the container exposing port 80 and, if it does, then browses to that port.) I'll add an issue to add that support.

In any case, I'm glad you've got things working and I really appreciate the time you took to work through these issues. You've provided some great feedback for how we can improve the product/documentation. Thanks!

@philliphoff
Copy link
Member

Added #764 for overriding the browser URL.

@philliphoff
Copy link
Member

Added #766 for improving the documentation related to Dockerfile generation.

@philliphoff
Copy link
Member

Closing this in favor of the individual issues this spawned, as the primary issue has been resolved.

@vscodebot vscodebot bot locked and limited conversation to collaborators Apr 1, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants