如何在 .Net Core 3、Visual Studio 2019 和 docker 中使用“dotnet watch run”

问题描述 投票:0回答:3

我正在使用 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
开头,但未检测到任何文件更改,也不会触发重建。

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

谢谢。

更新

使用此 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

还有这个 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,一切都会正常。

为什么?

2023 年更新

Visual Studio 2022 17.7 或更高版本完全支持开箱即用! GitHub 问题参考

c# visual-studio entity-framework docker asp.net-core
3个回答
9
投票

当您想在本地运行

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

撰写文件不是从基础 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>

3
投票

像这样更改入口点,

ENTRYPOINT dotnet watch run --no-restore

每当发生新的更改时,这将重建服务器。


0
投票
本地计算机上和 Docker 容器内的

obj/

bin/
 文件夹内的文件必须不同。如果它们重叠,您就会收到错误。

要解决该问题,您可以将

obj/

bin/
 的位置更改为
@Mike Hawkins 解释道。

但是还有另一种解决方案。

使用本地

bin/

obj/
 绑定挂载卷覆盖您的 docker 
bin/
obj/
 目录,为了避免这种过度,您必须告诉 docker 
bin/
obj/
 文件夹不应被覆盖外部。这可以通过另一卷(匿名)来实现。 Docker 会评估所有卷,如果它们重叠,则较长的内部路径会占主导地位。

您可以在 Dockerfile 中定义此卷

VOLUME ["/app/path/to/bin"] VOLUME ["/app/path/to/obj"]
或者在 docker-compose 中

volumes: - ./DockerTestApp:/app - /app/path/to/bin - /app/path/to/obj
此方法的缺点是需要显式键入整个解决方案中的所有 

bin/

obj/
 文件夹路径。

© www.soinside.com 2019 - 2024. All rights reserved.