CZEMacLeod / MSBuild.SDK.SystemWeb

This MSBuild SDK is designed to allow for the easy creation and use of SDK (shortform) projects targeting ASP.NET 4.x using System.Web.
MIT License
151 stars 8 forks source link

Add container support? #9

Open fretje opened 3 years ago

fretje commented 3 years ago

This is probably something that should be posted to the Visual Studio Team... But maybe someone here can shed some light on this?

I have tried to get container support running on a project created with this sdk, but it doesn't seem to work. (See here for the official docs on this container support)

I have added a package reference to the container tools:

<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.10.13" />

I have added a Dockerfile and a .dockerignore file.

I have added a profile to the launchsettings:

"Docker": {
  "commandName": "Docker",
  "launchBrowser": true,
  "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}",
  "publishAllPorts": true,
  "useSSL": true
}

But when I try to debug or run the project using that profile, I get an error message "the project doesn't know how to run the profile Docker":

image

TheJayMann commented 3 years ago

Do these steps work successfully if trying to use them on an ASP.NET Core application? If this is the case, then it's possible that the Microsoft.NET.Sdk.Web contains something that allows the package to work that Microsoft.NET.Sdk (which this project imports) does not, or, perhaps, Visual Studio itself likes to treat Microsoft.NET.Sdk.Web projects special.

If ASP.NET Core applications do not work for you following the steps described, then you likely need to first troubleshoot that problem. If, however, ASP.NET Core applications do work, then we would need to find out what allows the Microsoft.NET.Sdk.Web SDK to work. I have a feeling that, if this is the case, it is likely a <ProjectCapability>.

CZEMacLeod commented 3 years ago

@fretje Looking through the notes on docker support - remember that you will have to use windows containers with IIS to get this to work as you are running under the Full Framework. There are some notes in the documentation about

If you are using the full .NET Framework console project template, the supported option is Add Container Orchestrator support after project creation, with options to use Service Fabric or Docker Compose. Adding support at project creation and Add Docker support for a single project without orchestration are not available options.

However, as @TheJayMann says - the Launch Profile option for docker seems likely to be lit up via a <ProjectCapability> It does seem like the package Microsoft.VisualStudio.Azure.Containers.Tools.Targets does have a couple of these included:

  <ItemGroup>
    <ProjectCapability Include="ContainerTargets" />
  </ItemGroup>
  <PropertyGroup>
    <HasContainerTargets>true</HasContainerTargets>
  </PropertyGroup>

and

  <ItemGroup>
    <ProjectCapability Include="BuildServiceTargets" />
  </ItemGroup>

Unfortunately I couldn't find any more information on how launchSettings commands were resolved - obviously there is Program, IIS Express and Docker but it is not obvious how these work.

It seems as if you can force the issue by creating a folder Container under obj, and adding an empty file called launch.sem Then if you just Build the project, it seems to create the container and launch it as expected. Note that the web browser does not launch, but if you look in the Docker Desktop UI, or the Containers window in VS you can see the container running, and browsing to the host port seems to work as expected. Obviously, this is not debugging the container, but you can do Debug->Attach to Process, select Docker (Windows Container), find the connection target, set the type to Managed 4.x code, show all users and select the w3wp.exe process. Altogether though it is not a great experience.

bachratyg commented 3 years ago

@CZEMacLeod

Unfortunately I couldn't find any more information on how launchSettings commands were resolved - obviously there is Program, IIS Express and Docker but it is not obvious how these work.

I believe a package (built-in or add-on) supports a launch command via IDebugProfileLaunchTargetsProvider.SupportsProfile. This component should then be decorated with AppliesTo that determines what project capabilities are required for the component to activate. This can be a complex expression e.g. Cap1&(Cap2|Cap3)

@fretje Could you try with these?

<ProjectCapability Include="ContainerToolsDebugging" />
<ProjectCapability Include="ContainerTargets" />
bachratyg commented 3 years ago

This lights up the Add > Docker Support... in the project context menu. Doesn't seem to work properly though.

<PropertyGroup>
    <ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
</PropertyGroup>
fretje commented 3 years ago

I am trying to convert an existing NetFramework4.8 (webapi) project to use this new SDK style. This NetFramework project has docker support enabled, and it is possible to build the docker container and debug the application inside the docker container all from visual studio. I actually enabled that support by specifying it while creating the project, but I think that is the same as not specifying it there and then simply adding it afterwards by right clicking on the project and add > docker support. Which is actually available for NetFramework projects even though the docs might state it otherwise.

I have created a brand new asp.net mvc (netframework) application and enabled docker support from the get go, just to test this out. This is the "Container Tools" output after creating the project:

========== Warming up container(s) for WebApplicationNetFramework ==========
Starting up container(s)...
docker build -f "C:\Users\fretje\source\repos\DockerSdkStyle\WebApplicationNetFramework\Dockerfile" --force-rm -t webapplicationnetframework:dev --build-arg "source=obj\Docker\empty" --label "com.microsoft.created-by=visual-studio" --label "com.microsoft.visual-studio.project-name=WebApplicationNetFramework" "C:\Users\fretje\source\repos\DockerSdkStyle\WebApplicationNetFramework" 
Sending build context to Docker daemon  3.584kB

Step 1/6 : FROM mcr.microsoft.com/dotnet/framework/aspnet:4.8-windowsservercore-ltsc2019
 ---> 8558397b56ab
Step 2/6 : ARG source
 ---> Running in 4b390cb85d90
Removing intermediate container 4b390cb85d90
 ---> 23c01119ba3c
Step 3/6 : WORKDIR /inetpub/wwwroot
 ---> Running in 6bffcf2d148f
Removing intermediate container 6bffcf2d148f
 ---> 822a1def8864
Step 4/6 : COPY ${source:-obj/Docker/publish} .
 ---> 31f910c32bcd
Step 5/6 : LABEL com.microsoft.created-by=visual-studio
 ---> Running in 028d2bb7f300
Removing intermediate container 028d2bb7f300
 ---> cccfa21ca4bd
Step 6/6 : LABEL com.microsoft.visual-studio.project-name=WebApplicationNetFramework
 ---> Running in 9549234dec8e
Removing intermediate container 9549234dec8e
 ---> d1873cb1c772
Successfully built d1873cb1c772
Successfully tagged webapplicationnetframework:dev
Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
docker run -dt -v "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\Remote Debugger:C:\remote_debugger:ro" -v "C:\Users\fretje\source\repos\DockerSdkStyle\WebApplicationNetFramework:C:\inetpub\wwwroot" -e "DEV_ENVIRONMENT=1" -e "VBCSCOMPILER_TTL=604800" -e "COMPLUS_ForceENC=1" -P --name WebApplicationNetFramework --entrypoint cmd webapplicationnetframework:dev /c "start /B C:\ServiceMonitor.exe w3svc & C:\remote_debugger\x64\msvsmon.exe /noauth /anyuser /silent /nostatus /noclrwarn /nosecuritywarn /nofirewallwarn /nowowwarn /fallbackloadremotemanagedpdbs /timeout:2147483646" 
4d05feb6daa35263cc9868cadca0d64f711818c72bdca5f302f8065e7cd0384b
docker exec 4d05feb6daa35263cc9868cadca0d64f711818c72bdca5f302f8065e7cd0384b cmd /c "C:\Windows\System32\inetsrv\appcmd.exe set config -section:system.applicationHost/applicationPools /[name='DefaultAppPool'].processModel.identityType:LocalSystem /commit:apphost & C:\Windows\System32\inetsrv\appcmd.exe set config -section:system.webServer/security/authentication/anonymousAuthentication /userName: /commit:apphost"
Applied configuration changes to section "system.applicationHost/applicationPools" for "MACHINE/WEBROOT/APPHOST" at configuration commit path "MACHINE/WEBROOT/APPHOST"
Applied configuration changes to section "system.webServer/security/authentication/anonymousAuthentication" for "MACHINE/WEBROOT/APPHOST" at configuration commit path "MACHINE/WEBROOT/APPHOST"
Trying to connect to 172.17.222.228 for debugging
Trying to connect to 172.17.222.228 for debugging
Container started successfully.
========== Finished ==========

Running and debugging the project in Docker works as you would expect.

For comparison, I have done the same for an ASP.NET Core Web project, but there everything comes in the "Build" output. There is no "Container Tools" output:

1>------ Build started: Project: WebApplicationNetCore, Configuration: Debug Any CPU ------
1>WebApplicationNetCore -> C:\Users\fretje\source\repos\DockerSdkStyle\WebApplicationNetCore\bin\Debug\net5.0\WebApplicationNetCore.dll
1>WebApplicationNetCore -> C:\Users\fretje\source\repos\DockerSdkStyle\WebApplicationNetCore\bin\Debug\net5.0\WebApplicationNetCore.Views.dll
1>docker build -f "C:\Users\fretje\source\repos\DockerSdkStyle\WebApplicationNetCore\Dockerfile" --force-rm -t webapplicationnetcore:dev --target base  --label "com.microsoft.created-by=visual-studio" --label "com.microsoft.visual-studio.project-name=WebApplicationNetCore" "C:\Users\fretje\source\repos\DockerSdkStyle"
1>Sending build context to Docker daemon  84.28MB
1>
1>Step 1/6 : FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
1>5.0: Pulling from dotnet/aspnet
...
1>f2250ff2c8dd: Pull complete
1>Digest: sha256:c0cc95b0d87a31401763f8c7b2a25aa106e7b45bfcaa2f302dc9d0ff5ab93fa2
1>Status: Downloaded newer image for mcr.microsoft.com/dotnet/aspnet:5.0
1> ---> 834c20869027
1>Step 2/6 : WORKDIR /app
1> ---> Running in 161b357d7430
1>Removing intermediate container 161b357d7430
1> ---> 58b55130c04c
1>Step 3/6 : EXPOSE 80
1> ---> Running in 7f4c46f6748a
1>Removing intermediate container 7f4c46f6748a
1> ---> 3d4fad8f210e
1>Step 4/6 : EXPOSE 443
1> ---> Running in 66b9461d041d
1>Removing intermediate container 66b9461d041d
1> ---> cc6bd66954a2
1>Step 5/6 : LABEL com.microsoft.created-by=visual-studio
1> ---> Running in c176d9ef762e
1>Removing intermediate container c176d9ef762e
1> ---> 5167d54a976b
1>Step 6/6 : LABEL com.microsoft.visual-studio.project-name=WebApplicationNetCore
1> ---> Running in cc0c4e0c88c0
1>Removing intermediate container cc0c4e0c88c0
1> ---> 6886a6aec2db
1>Successfully built 6886a6aec2db
1>Successfully tagged webapplicationnetcore:dev
1>Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
1>docker run -dt -v "C:\Users\fretje\onecoremsvsmon\16.9.1154.0:C:\remote_debugger:ro" -v "C:\Users\fretje\source\repos\DockerSdkStyle\WebApplicationNetCore:C:\app" -v "C:\Users\fretje\source\repos\DockerSdkStyle:c:\src" -v "C:\Users\fretje\AppData\Roaming\Microsoft\UserSecrets:C:\Users\ContainerUser\AppData\Roaming\Microsoft\UserSecrets:ro" -v "C:\Users\fretje\AppData\Roaming\ASP.NET\Https:C:\Users\ContainerUser\AppData\Roaming\ASP.NET\Https:ro" -v "C:\Users\fretje\.nuget\packages\:c:\.nuget\fallbackpackages2" -v "C:\Program Files\dotnet\sdk\NuGetFallbackFolder:c:\.nuget\fallbackpackages" -e "DOTNET_USE_POLLING_FILE_WATCHER=1" -e "ASPNETCORE_LOGGING__CONSOLE__DISABLECOLORS=true" -e "ASPNETCORE_ENVIRONMENT=Development" -e "ASPNETCORE_URLS=https://+:443;http://+:80" -e "NUGET_PACKAGES=c:\.nuget\fallbackpackages2" -e "NUGET_FALLBACK_PACKAGES=c:\.nuget\fallbackpackages;c:\.nuget\fallbackpackages2" -P --name WebApplicationNetCore --entrypoint C:\remote_debugger\x64\msvsmon.exe webapplicationnetcore:dev /noauth /anyuser /silent /nostatus /noclrwarn /nosecuritywarn /nofirewallwarn /nowowwarn /fallbackloadremotemanagedpdbs /timeout:2147483646 /LogDebuggeeOutputToStdOut
1>0f882de424f9864e76d925c88f8f09c2cb3ac959204662629122bcf49990a182
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========

Here also Debugging works fine.

Both projects are available here: https://github.com/fretje/DockerSdkStyle

I'll try and create a similar sdkstyle project in the same repo and see where I get with some of the suggestions here...

fretje commented 3 years ago

Adding

<ItemGroup>
  <ProjectCapability Include="ContainerToolsDebugging" />
</ItemGroup>

Seems to have gotten me further. Now the "Container Tools" output looks promising:

Docker Desktop is running.
========== Verifying Docker OS ==========
Verifying that Docker Desktop's operating system mode matches the project's target operating system...
Docker Desktop's operating system mode matches the project's target operating system.
========== Pulling Required Images ==========
Checking for missing Docker images...
Pulling Docker images. To cancel this download, close the command prompt window.
docker pull mcr.microsoft.com/dotnet/framework/aspnet:4.8-windowsservercore-ltsc2019
Docker images are ready.
========== Warming up container(s) for WebApplicationSystemWeb ==========
Starting up container(s)...
docker run -dt -v "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\Remote Debugger:C:\remote_debugger:ro" -v "C:\Users\fretje\source\repos\DockerSdkStyle\WebApplicationSystemWeb:C:\inetpub\wwwroot" -e "DEV_ENVIRONMENT=1" -e "VBCSCOMPILER_TTL=604800" -e "COMPLUS_ForceENC=1" -P --name WebApplicationSystemWeb --entrypoint cmd webapplicationsystemweb:dev /c "start /B C:\ServiceMonitor.exe w3svc & C:\remote_debugger\x64\msvsmon.exe /noauth /anyuser /silent /nostatus /noclrwarn /nosecuritywarn /nofirewallwarn /nowowwarn /fallbackloadremotemanagedpdbs /timeout:2147483646" 
a5a7662449e430689b8e4ba30272009ddf4b6968617d247d26bc0c2a7c4eb9bd
Container started successfully.
========== Finished ==========

Starting debug build output looks like this:

Build started...
1>------ Build started: Project: WebApplicationSystemWeb, Configuration: Debug Any CPU ------
1>
1>Restore operation started...
1>
1>5 libraries restored in 0,5 seconds
1>WebApplicationSystemWeb -> C:\Users\fretje\source\repos\DockerSdkStyle\WebApplicationSystemWeb\bin\WebApplicationSystemWeb.dll
1>docker rm -f a5a7662449e430689b8e4ba30272009ddf4b6968617d247d26bc0c2a7c4eb9bd
1>a5a7662449e430689b8e4ba30272009ddf4b6968617d247d26bc0c2a7c4eb9bd
1>docker run -dt -v "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\Remote Debugger:C:\remote_debugger:ro" -v "C:\Users\fretje\source\repos\DockerSdkStyle\WebApplicationSystemWeb:C:\inetpub\wwwroot" -e "DEV_ENVIRONMENT=1" -e "VBCSCOMPILER_TTL=604800" -e "COMPLUS_ForceENC=1" -P --name WebApplicationSystemWeb --entrypoint cmd webapplicationsystemweb:dev /c "start /B C:\ServiceMonitor.exe w3svc & C:\remote_debugger\x64\msvsmon.exe /noauth /anyuser /silent /nostatus /noclrwarn /nosecuritywarn /nofirewallwarn /nowowwarn /fallbackloadremotemanagedpdbs /timeout:2147483646"
1>806b1dd3f92fc81a012266d39f44291257ea1ee095fbf80d51ac740817dd4e5c
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========

But then I get an error Failed to find path of the output assembly for project WebApplicationSystemWeb.:

image

The project has been added to the test repository...

CZEMacLeod commented 3 years ago

@fretje Great to have all 3 types in a repo for comparison. I had pretty much got as far as you, with the same error message. I wonder if we might need to build a specialized IDebugLaunchProvider which works for the MSBuild.SDK.SystemWeb project type. Either that or maybe we need a friendly MS/VS developer to give us some hints at what is happening inside the VS Docker support code at that point?

bachratyg commented 3 years ago

I hope not. Writing an IDebugLaunchProvider is no easy task. Most of these errors indicate that some MSBuild property is not set but is expected by the docker package. This could be either because it's in NET.Sdk.Web or some other lightup that would trigger it is still missing.

bachratyg commented 3 years ago

Tried this with a simple console app, the only difference was the target framework. Works for net5, same error message for net48. Unfortunately it looks like the ContainerBuildAndLaunch task in Microsoft.VisualStudio.Azure.Containers.Tools.Targets has some hardwired behavior for framework vs core. 😞

CZEMacLeod commented 3 years ago

@bachratyg I've looked through the source of the ContainerBuildAndLaunch task itself, and while it does have differences between the NETFramework and NETCore implementations, I'm not convinced this is where the error is occurring. Specifically, as the actual build succeeds, and the container is actually launched. You can actually manually attach the debugger to the container and that bit works. I think this is actually in the internal VS Extension that handles the IDebugLaunchProvider implementation for Docker.

bachratyg commented 3 years ago

AFAIK the package is not OSS. Where did you get the source?

slang25 commented 3 years ago

I don't think it's developed in the open, but you can download the nupkg from here and extract the target file: https://www.nuget.org/packages/Microsoft.VisualStudio.Azure.Containers.Tools.Targets/

fretje commented 3 years ago

Okay, just a heads up: I got a response from an MSFT engineer on the issue I opened with the container tools team (see above):

@fretje I did a quick look and it appears the issue is that when the ASP.NET project is using the new SDK style the debugging goes through a different entry-point which in our case only supports .NET Core projects. We've added supporting this to our backlog.

CZEMacLeod commented 3 years ago

I am looking to try and capture information from the issues into documentation, and while this is an ongoing issue pending some feedback from the docker tools team, I feel it might be useful to capture the current state of the issue as perhaps a known limitation or similar - obviously with a link to this issue. Documentation?

julealgon commented 1 year ago

@fretje / @CZEMacLeod , are there any updates on this?

@CZEMacLeod I see you added the "known limitation" label somewhat recently. Are there any news on this or was that done only because you created the label recently (or forgot to tag it before)?

CZEMacLeod commented 1 year ago

As far as I can tell, there seems to be some support in the latest docker container targets, but debugging still fails to automatically attach. If you do debug and get the error, you can then manually attach the debugger successfully and debug inside the container. Unfortunately, this is all dependent on code inside of VS itself, so is not something that can be dealt with here. Hence the known limitation label.