3

I'm running the basic dotnetcore example in docker and it works fine. Everything builds and my API is available. It also listens to live-changes which is perfect. You can find the Dockerfile and docker-compose at the bottom of the question.

However, I'm trying to work with the code using Visual-studio-code (insiders and regular) combined with omnisharp (default c# extension) and it keeps crashing on me.

It will work for a few seconds and after that stick me with 180+ "problems", all of which are false (the app works..)

The output doesn't indicate anything imo (from restart till crash):

Starting OmniSharp server at 7/3/2018, 11:52:55 AM
    Target: /home/mastermindzh/code/

OmniSharp server started
    Path: /home/mastermindzh/.vscode-insiders/extensions/ms-vscode.csharp-1.15.2/.omnisharp/1.30.1/run
    PID: 2323

[info]: OmniSharp.Stdio.Host
        Starting OmniSharp on arch 0.0 (x64)
[info]: OmniSharp.MSBuild.Discovery.MSBuildLocator
        Located 1 MSBuild instance(s)
            1: StandAlone 15.0 - "/home/mastermindzh/.vscode-insiders/extensions/ms-vscode.csharp-1.15.2/.omnisharp/1.30.1/omnisharp/msbuild/15.0/Bin"
[info]: OmniSharp.MSBuild.Discovery.MSBuildLocator
        MSBUILD_EXE_PATH environment variable set to '/home/mastermindzh/.vscode-insiders/extensions/ms-vscode.csharp-1.15.2/.omnisharp/1.30.1/omnisharp/msbuild/15.0/Bin/MSBuild.dll'
[info]: OmniSharp.MSBuild.Discovery.MSBuildLocator
        Registered MSBuild instance: StandAlone 15.0 - "/home/mastermindzh/.vscode-insiders/extensions/ms-vscode.csharp-1.15.2/.omnisharp/1.30.1/omnisharp/msbuild/15.0/Bin"
            MSBuildExtensionsPath = /home/mastermindzh/.vscode-insiders/extensions/ms-vscode.csharp-1.15.2/.omnisharp/1.30.1/omnisharp/msbuild
            BypassFrameworkInstallChecks = true
            CscToolPath = /home/mastermindzh/.vscode-insiders/extensions/ms-vscode.csharp-1.15.2/.omnisharp/1.30.1/omnisharp/msbuild/15.0/Bin/Roslyn
            CscToolExe = csc.exe
            MSBuildToolsPath = /home/mastermindzh/.vscode-insiders/extensions/ms-vscode.csharp-1.15.2/.omnisharp/1.30.1/omnisharp/msbuild/15.0/Bin
[info]: OmniSharp.Cake.CakeProjectSystem
        Detecting Cake files in '/home/mastermindzh/code/'.
[info]: OmniSharp.Cake.CakeProjectSystem
        Could not find any Cake files
[info]: OmniSharp.DotNet.DotNetProjectSystem
        Initializing in /home/mastermindzh/code/
[info]: OmniSharp.DotNet.DotNetProjectSystem
        Auto package restore: False
[info]: OmniSharp.DotNet.DotNetProjectSystem
        Update workspace context
[info]: OmniSharp.DotNet.DotNetProjectSystem
        Resolving projects references
[info]: OmniSharp.MSBuild.ProjectSystem
        No solution files found in '/home/mastermindzh/code/'
[info]: OmniSharp.MSBuild.ProjectManager
        Queue project update for '/home/mastermindzh/code//api/api.csproj'
[info]: OmniSharp.Script.ScriptProjectSystem
        Detecting CSX files in '/home/mastermindzh/code/'.
[info]: OmniSharp.Script.ScriptProjectSystem
        Could not find any CSX files
[info]: OmniSharp.Stdio.Host
        Invoking Workspace Options Provider: OmniSharp.Roslyn.CSharp.Services.CSharpWorkspaceOptionsProvider
[info]: OmniSharp.Stdio.Host
        Configuration finished.
[info]: OmniSharp.Stdio.Host
        Omnisharp server running using Stdio at location '/home/mastermindzh/code/' on host 30096.
[info]: OmniSharp.MSBuild.ProjectManager
        Loading project: /home/mastermindzh/code//api/api.csproj
[info]: OmniSharp.MSBuild.ProjectManager
        Adding project '/home/mastermindzh/code//api/api.csproj'
[info]: OmniSharp.MSBuild.ProjectManager
        Update project: api

After this the extension just doesn't work anymore untill I restart it and it crashes again. This only fails when launching in Docker or from the cli, if I run the app through vscode (something I don't want to do) it works fine.

Dockerfile:

FROM microsoft/dotnet:2.1-sdk-stretch
WORKDIR /app
EXPOSE 5000
CMD dotnet restore && dotnet watch run

Compose:

version: "3"
services:

    web:
        build:
            context: ./../../api
            dockerfile: ./../docker/images/api/Dockerfile
        ports:
            - "5000:5000"
            - "5001:5001"
        volumes:
            - ./../../api/:/app
        depends_on:
             - db

My best guess so far is that it's got something to do with dotnet restore and/or the bin/obj folders. Running a dotnet clean and then starting the app makes no difference.

Any help would be greatly appreciated.

Rick van Lieshout
  • 2,276
  • 2
  • 22
  • 39

3 Answers3

0

Hi Rick were you able to get this figured out? I'm hitting the same problem, trying to run a debugger using the Omnisharp extension inside a docker container.

I saw those bin/obj references you mentioned and it seems to be due to how .net configures the runtime environment. This seems to be based on the location of the dotnet shared folder. This post explains part of it: What is the purpose of msbuild's GenerateRuntimeConfigurationFiles?

I think the problem is that this shared folder is different from the actual host (machine I'm running on) versus what is on the docker container. So when you run dotnet in the container, it configures the runtime based on what is in that container. This throws off Omnisharp since it is running outside the container.

I think we could define and volume mount those shared folders as part of the dockerfile (or docker-compose). But I've yet to get something working. I know this is from few months back but checking if you figured this out. THanks!

John Lee
  • 1,357
  • 1
  • 13
  • 26
  • I did not get it to work, no. I created an issue on github but that has gone unanswered up till now too. The best thing we can do is hope for upvotes on the issue/ this question so more people see it. – Rick van Lieshout Oct 23 '18 at 08:11
  • Thanks for the update. I'll keep an eye on the github side to see how it progresses. I'll post here again if I do figure something else out before then. Thanks again! – John Lee Oct 23 '18 at 20:26
0

I have an update. If you are still working this, perhaps this could help.

So as mentioned in my prior post, the problem is that your VSCode debugger is running outside the docker container. What you need is to launch a remote debugger in that container and then have VSCode attach into it.

I followed an example posted here. This is for a console app. https://github.com/sleemer/docker.dotnet.debug

I expanded the above example for webapi and mvc apps. You can see that here: https://github.com/johnlee/dockerdotnetcorevscode

I have a write up on it as well, though its mostly for my own notes so may not be the easiest to read. https://solidfish.com/building-net-core-apps-docker-with-vscode-on-mac-or-windows/

Another option for you is to actually run VSCode inside the docker container. This is perhaps a bit overkill but it seems to be possible. https://www.aaron-powell.com/posts/2017-09-21-vscode-linux-docker-windows/

John Lee
  • 1,357
  • 1
  • 13
  • 26
0

I managed to find a configuration that makes it workable when using this workflow of "mapped project folder with docker compose + dotnet watch" that gives live updates of the code without having to rebuild the container everytime.

First, I'm going to post the full docker-compose.yml and then I'm going to explain the necessary configuration.

This is the full docker-compose.yml for a .NET project (that needs to work with the VSCode extension):

services:
  dotnet-api:
    image: mcr.microsoft.com/dotnet/core/sdk:2.2.402
    command: [sh, -c, "dotnet watch run"]
    working_dir: /app
    volumes:
       - .:/app
       - /usr/bin/dotnet:/usr/bin/dotnet
       - /usr/share/dotnet:/usr/share/dotnet
       - ${HOME}/.nuget:${HOME}/.nuget
    environment:
       HOME: /home/${USER}

Notice that I'm using .NET SDK 2.2 here (as I'm maintaining a legacy application), but you should be able to adapt it to your needs. Also you might need to change the working_dir variable to the path where your API csproj file is located or specify the project to be run with dotnet watch run --project YourProject.API/YourProject.API.csproj.

Now for the step by step explanation.

Mounting your .NET Environment into the container

The communication of the VS Code C# extension and omnisharp interact with the omnisharp sdk mainly through the dotnet cli tool, so you have to map it to your container as well, hence theses lines:

services:
  dotnet-api:
    volumes:
      - /usr/bin/dotnet:/usr/bin/dotnet
      - /usr/share/dotnet:/usr/share/dotnet

Be mindful that this will overwrite the sdk that is in the container, so you lose a little bit of the benefit of using the SDK container in the first place.

Mapping your current user $HOME the container

You also need to map your current user nuget folder to the container in the path that is expected by omnisharp, which is $HOME/.nuget, but only mounting the .nuget folder is not enough because the container doesn't have the $HOME variable set and if you don't set it, omnisharp will look for packages in the root folder and will fail because it doesn't have permissions.

So you add these lines:

services:
  dotnet-api:
    volumes:
      - ${HOME}/.nuget:${HOME}/.nuget
    environment:
      HOME: /home/${USER}

And that should be able to get the C# extension for VS Code to stop showing errors, but with this solution the debugger probably won't work because you need to attach to the process that is running your executable, which is another problem entirely.


Even though I'm overwriting the SDK that is inside the container, which loses a little bit of the benefit of Docker, I still like to use docker compose so that I can easily spin up multiple containers and try out new containers when necessary, so this configuration is still worth it for me, as it is used only in a development environment.

Eduardo macedo
  • 762
  • 1
  • 4
  • 16