How to use “dotnet watch run” with .Net Core 3, Visual Studio 2019 and docker

对着背影说爱祢 提交于 2021-02-07 08:22:54

问题


I'm playing with docker and .NET Core 3 using Visual Studio 2019. I containerize my application by adding the Dockerfile to my project (right click on the project -> Add -> Docker Support) and I was able to launch it, but now I want to use dotnet watch run inside the container.

This is the generated Dockerfile:

FROM mcr.microsoft.com/dotnet/core/aspnet:3.0-buster-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

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

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

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

and I modified it like so:

FROM mcr.microsoft.com/dotnet/core/sdk:3.0-buster AS build
ENV DOTNET_USE_POLLING_FILE_WATCHER 1
WORKDIR /src
EXPOSE 80
EXPOSE 443
COPY ["DockerTestApp/DockerTestApp.csproj", "DockerTestApp/"]
RUN dotnet restore "DockerTestApp/DockerTestApp.csproj"
ENTRYPOINT ["dotnet", "watch", "run"] 

The container started with dotnet watch run but any file change isn't detected and the rebuild is not triggered.

Should I have to mount a volume from my code directory to the container in order to make it work?

Thanks.

UPDATE

with this Dokerfile

FROM mcr.microsoft.com/dotnet/core/sdk:3.0

ENV DOTNET_USE_POLLING_FILE_WATCHER 1

WORKDIR /app
COPY . .
ENTRYPOINT dotnet watch run  --urls=https://+:5001 --project DocketTestApp.csproj

and this docker-compose.yml

version: '3.4'

services:
  dotnet-watch-docker-example:
    container_name: dotnet_watch_docker_example
    image: giuseppeterrasi/dotnet-watch-docker-example
    build:
      context: ./DocketTestApp/
    ports:
      - 5001:5001
    volumes:
      - './DocketTestApp/:/app/'
    depends_on: 
      - db
  db:
    image: mysql
    restart: always
    ports:
        - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: testPassword
      MYSQL_DATABASE: testDB
      MYSQL_USER: testUser
      MYSQL_PASSWORD: test

It works, but if I add a DbContext, Visual Studio misses the Entity Framework reference if the container is started. If I stop the container and reload Visual Studio everything is ok.

Why?


回答1:


Change the entry point like this,

ENTRYPOINT dotnet watch run --no-restore

This will rebuild the server whenever new changes occurs.




回答2:


You can omit using a custom Dockerfile when you want to run dotnet watch run locally.

Consider the following docker-compose.yml file:

version: '3.4'

services:
  dotnet-watch-docker-example:
    container_name: dotnet_watch_docker_example
    image: mcr.microsoft.com/dotnet/core/sdk:3.0
    ports:
      - 5001:5001
    volumes:
      - ./DockerTestApp:/app
    working_dir: /app
    command: dotnet watch run

Instead of creating a custom image from the base dotnet sdk image, the compose file simply starts a container based on the base dotnet sdk image. It then creates a volume that maps the local directory containing your project to the directory /app inside the container. It then sets the working directory inside the container to /app, and lastly, it runs the dotnet watch run command inside the container.

To fix your problem with the Entity framework reference, add the following Directory.Build.props file inside the project directory. This file instructs MSBUILD to place /bin and /obj files in different directories (container/local) dependent upon the executing environment. This way, no conflicts emerge.

<Project>
    <PropertyGroup>
        <DefaultItemExcludes>$(DefaultItemExcludes);$(MSBuildProjectDirectory)/obj/**/*</DefaultItemExcludes>
        <DefaultItemExcludes>$(DefaultItemExcludes);$(MSBuildProjectDirectory)/bin/**/*</DefaultItemExcludes>
    </PropertyGroup>
    <PropertyGroup Condition="'$(DOTNET_RUNNING_IN_CONTAINER)' == 'true'">
        <BaseIntermediateOutputPath>$(MSBuildProjectDirectory)/obj/container/</BaseIntermediateOutputPath>
        <BaseOutputPath>$(MSBuildProjectDirectory)/bin/container/</BaseOutputPath>
    </PropertyGroup>
    <PropertyGroup Condition="'$(DOTNET_RUNNING_IN_CONTAINER)' != 'true'">
        <BaseIntermediateOutputPath>$(MSBuildProjectDirectory)/obj/local/</BaseIntermediateOutputPath>
        <BaseOutputPath>$(MSBuildProjectDirectory)/bin/local/</BaseOutputPath>
    </PropertyGroup>
</Project>


来源:https://stackoverflow.com/questions/59017082/how-to-use-dotnet-watch-run-with-net-core-3-visual-studio-2019-and-docker

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!