dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.37k stars 9.99k forks source link

Dotnet watch does not trigger on file change with Windows Containers #22797

Open nickwesselman opened 4 years ago

nickwesselman commented 4 years ago

Steps to reproduce the issue

  1. Clone the dotnet-docker repository
  2. Switch Docker to Windows Containers
  3. docker run --rm -it -p 8000:80 -v c:\dev\dotnet-docker\samples\aspnetapp:c:\app\ -w \app\aspnetapp -e ASPNETCORE_URLS=http://*:80 --name aspnetappsample mcr.microsoft.com/dotnet/core/sdk:3.1 dotnet watch run --no-launch-profile
    • Adjust path as needed
  4. Browse to http://localhost:8000/
  5. Make a change in samples\aspnetapp\aspnetapp\Pages\Index.cshtml and save
  6. Refresh browser

Expected behavior

Actual behavior

Output with -v does indicate that the polling file watcher is enabled, and that the change is seen, but the dotnet process can't be stoppped.

watch : Polling file watcher is enabled
watch : Running MSBuild target 'GenerateWatchList' on 'C:\app\aspnetapp\aspnetapp.csproj'
watch : Started 'dotnet' with process id 1512
watch : Process id 1512 ran for 1705ms
watch : Watching 13 file(s) for changes
watch :   -> C:\app\aspnetapp\Pages\Error.cshtml
watch :   -> C:\app\aspnetapp\Pages\Index.cshtml
watch :   -> C:\app\aspnetapp\Pages\Privacy.cshtml
watch :   -> C:\app\aspnetapp\Pages\Shared\_Layout.cshtml
watch :   -> C:\app\aspnetapp\Pages\Shared\_ValidationScriptsPartial.cshtml
watch :   -> C:\app\aspnetapp\Pages\_ViewImports.cshtml
watch :   -> C:\app\aspnetapp\Pages\_ViewStart.cshtml
watch :   -> C:\app\aspnetapp\Pages\Error.cshtml.cs
watch :   -> C:\app\aspnetapp\Pages\Index.cshtml.cs
watch :   -> C:\app\aspnetapp\Pages\Privacy.cshtml.cs
watch :   -> C:\app\aspnetapp\Program.cs
watch :   -> C:\app\aspnetapp\Startup.cs
watch :   -> C:\app\aspnetapp\aspnetapp.csproj
watch : Started 'dotnet' with process id 1816
watch : Running dotnet with the following arguments: run --no-launch-profile
watch : Started
warn: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[60]
      Storing keys in a directory 'C:\Users\ContainerUser\AppData\Local\ASP.NET\DataProtection-Keys' that may not be per
sisted outside of the container. Protected data will be unavailable when container is destroyed.
info: Microsoft.Hosting.Lifetime[0]
      Now listening on: http://[::]:80
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Production
info: Microsoft.Hosting.Lifetime[0]
      Content root path: C:\app\aspnetapp
watch : Killing process 1816
watch : Error while killing process 'dotnet run --no-launch-profile': The system cannot find the file specified.
watch : System.ComponentModel.Win32Exception (2): The system cannot find the file specified.
   at System.Diagnostics.Process.StartWithCreateProcess(ProcessStartInfo startInfo)
   at System.Diagnostics.Process.Start()
   at System.Diagnostics.Process.Start(ProcessStartInfo startInfo)
   at Microsoft.Extensions.Internal.ProcessExtensions.RunProcessAndWaitForExit(String fileName, String arguments, TimeSp
an timeout, String& stdout) in C:\dev\aspnetcore\src\Shared\Process\ProcessExtensions.cs:line 108
   at Microsoft.Extensions.Internal.ProcessExtensions.KillTree(Process process, TimeSpan timeout) in C:\dev\aspnetcore\s
rc\Shared\Process\ProcessExtensions.cs:line 25
   at Microsoft.Extensions.Internal.ProcessExtensions.KillTree(Process process) in C:\dev\aspnetcore\src\Shared\Process\
ProcessExtensions.cs:line 18
   at Microsoft.DotNet.Watcher.Internal.ProcessRunner.ProcessState.TryKill() in C:\dev\aspnetcore\src\Tools\dotnet-watch
\src\Internal\ProcessRunner.cs:line 152

Additional information (e.g. issue happens only occasionally)

This seems to work fine with Linux Containers:

docker run --rm -it -p 8000:80 -v c:\dev\dotnet-docker\samples\aspnetapp:/app -w /app/aspnetapp -e ASPNETCORE_URLS=http://+:80 --name aspnetappsample mcr.microsoft.com/dotnet/core/sdk:3.1 dotnet watch run --no-launch-profile

Output of docker version

Client: Docker Engine - Community
 Version:           19.03.8
 API version:       1.40
 Go version:        go1.12.17
 Git commit:        afacb8b
 Built:             Wed Mar 11 01:23:10 2020
 OS/Arch:           windows/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          19.03.8
  API version:      1.40 (minimum version 1.24)
  Go version:       go1.12.17
  Git commit:       afacb8b
  Built:            Wed Mar 11 01:37:20 2020
  OS/Arch:          windows/amd64
  Experimental:     false

Output of docker info

Client:
 Debug Mode: false

Server:
 Containers: 2
  Running: 0
  Paused: 0
  Stopped: 2
 Images: 132
 Server Version: 19.03.8
 Storage Driver: windowsfilter
  Windows:
 Logging Driver: json-file
 Plugins:
  Volume: local
  Network: ics internal l2bridge l2tunnel nat null overlay private transparent
  Log: awslogs etwlogs fluentd gcplogs gelf json-file local logentries splunk syslog
 Swarm: inactive
 Default Isolation: hyperv
 Kernel Version: 10.0 18363 (18362.1.amd64fre.19h1_release.190318-1202)
 Operating System: Windows 10 Enterprise Version 1909 (OS Build 18363.836)
 OSType: windows
 Architecture: x86_64
 CPUs: 12
 Total Memory: 31.81GiB
 Name: LT-NWE1-T-US
 ID: KJ3K:R3GY:FLRD:BAJT:4KZW:LFB3:KPOO:JMA7:Y5Y7:UYWE:MPYU:2M7U
 Docker Root Dir: C:\ProgramData\Docker
 Debug Mode: true
  File Descriptors: -1
  Goroutines: 28
  System Time: 2020-06-09T11:49:31.7353616-04:00
  EventsListeners: 1
 Registry: https://index.docker.io/v1/
 Labels:
 Experimental: false
 Insecure Registries:
  127.0.0.0/8
 Live Restore Enabled: false
 Product License: Community Engine
nickwesselman commented 4 years ago

This appears to be due to the fact that dotnet watch requires taskkill, which is not on the nanoserver base images. See StefanScherer/dockerfiles-windows#285.

Somewhat heavy workaround is to create a custom SDK image based on servercore.

MichaelSimons commented 4 years ago

Another scenario that would benefit from having supported .NET Core servercore based images - https://github.com/dotnet/dotnet-docker/issues/1852

MichaelSimons commented 4 years ago

Moved to aspnetcore since this is a general issue with dotnet watch not supporting Nano Server.

nickwesselman commented 4 years ago

To save others who may attempt the same, I tried adding taskkill.exe to nanoserver, but it must have other dependencies, as it does not seem to execute.

Dockerfile

# escape=`

FROM mcr.microsoft.com/windows/servercore:ltsc2019 as servercore
FROM mcr.microsoft.com/dotnet/core/sdk:3.1
COPY --from=servercore ["C:\\windows\\system32\\taskkill.exe", "C:\\windows\\system32\\"]

Build and run

docker build . -t dotnetwatchnano
docker run --rm -it -p 8000:80 -v c:\dev\dotnet-docker\samples\aspnetapp:c:\app\ -w \app\aspnetapp -e ASPNETCORE_URLS=http://*:80 --name aspnetappsample dotnetwatchnano dotnet watch run --no-launch-profil

Attach shell

Microsoft Windows [Version 10.0.18363.836]
(c) 2019 Microsoft Corporation. All rights reserved.

C:\app\aspnetapp>taskkill

C:\app\aspnetapp>taskkill

C:\app\aspnetapp>taskkill /?

C:\app\aspnetapp>
mkArtakMSFT commented 4 years ago

Thanks for contacting us. We're moving this issue to the Next sprint planning milestone for future evaluation / consideration. We will evaluate the request when we will planning the work for the next milestone. To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.

nickwesselman commented 4 years ago

Please consider for .NET 6, if not sooner. We are heavily investing in Docker and ASP.NET Core, and dotnet watch is a great way for Sitecore devs to speed up developer iterations in our container environments:

https://github.com/Sitecore/Helix.Examples/blob/master/examples/helix-basic-aspnetcore/docker/build/rendering/Dockerfile

nickwesselman commented 3 years ago

In .NET 5 it's much easier to work around this as there are now Server Core containers available. πŸŽ‰πŸŽ‰πŸŽ‰

dotnet/dotnet-docker#2377