【问题标题】:How to use "dotnet watch run" with .Net Core 3, Visual Studio 2019 and docker如何在 .Net Core 3、Visual Studio 2019 和 docker 中使用“dotnet watch run”
【发布时间】:2020-03-19 20:58:46
【问题描述】:

我正在使用 Visual Studio 2019 使用 docker 和 .NET Core 3。我通过将 Dockerfile 添加到我的项目(右键单击项目 -> 添加 -> Docker 支持)来对我的应用程序进行容器化,并且我能够启动它,但现在我想在容器内使用dotnet watch run

这是生成的 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"]

我是这样修改的:

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"] 

容器以dotnet watch run 启动,但未检测到任何文件更改,也未触发重建。

我是否必须将代码目录中的卷挂载到容器中才能使其工作?

谢谢。

更新

使用这个 Dockerfile

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

还有这个 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

它可以工作,但如果我添加 DbContext,Visual Studio 会在容器启动时错过实体框架引用。如果我停止容器并重新加载 Visual Studio,一切正常。

为什么?

【问题讨论】:

    标签: c# visual-studio entity-framework docker asp.net-core


    【解决方案1】:

    当您想在本地运行 dotnet watch run 时,可以省略使用自定义 Dockerfile。

    考虑以下 docker-compose.yml 文件:

    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
    

    compose 文件不是从基本 dotnet sdk 映像创建自定义映像,而是简单地启动一个基于基本 dotnet sdk 映像的容器。然后它创建一个卷,将包含您的项目的本地目录映射到容器内的目录 /app。然后将容器内的工作目录设置为 /app,最后在容器内运行 dotnet watch run 命令。

    要解决实体框架参考的问题,请在项目目录中添加以下 Directory.Build.props 文件。该文件指示 MSBUILD 将 /bin 和 /obj 文件放在不同的目录(容器/本地)中,具体取决于执行环境。这样就不会出现冲突。

    <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>
    

    【讨论】:

    • 感谢您的回复。我已经对其进行了测试,并且正确创建了两个目录 obj/container 和 obj/local,第一个是在启动 docker-compose up 之后,第二个是在 Visual Studio 构建解决方案时,但是 Visual Studio 在 docker 时仍然错过了 EntityFramework 引用正在运行
    • 尝试删除引用EntityFramework的项目中的obj/和bin/文件夹,然后重新打开Visual Studio。
    • 在我删除初始 obj 和 bin 目录并重新启动 Omnisharp 后,这对我来说非常有效。
    • @ZacBall 很高兴听到!
    【解决方案2】:

    像这样改变入口点,

    ENTRYPOINT dotnet watch run --no-restore
    

    这将在发生新更改时重建服务器。

    【讨论】:

    • 感谢您的回复,但它不起作用,仍然没有检测到任何变化。
    猜你喜欢
    • 2020-02-28
    • 1970-01-01
    • 2017-03-02
    • 2019-08-25
    • 1970-01-01
    • 2022-11-19
    • 2021-03-22
    • 2020-07-04
    • 2020-01-25
    相关资源
    最近更新 更多