![](/img/trans.png)
[英]ASP.Net Core app works in visual studio but not with dotnet run
[英]How to use "dotnet watch run" with .Net Core 3, Visual Studio 2019 and docker
我正在使用 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,一切正常。
为什么?
当您想在本地运行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>
像这样更改入口点,
ENTRYPOINT dotnet watch run --no-restore
每当发生新的更改时,这将重建服务器。
obj/
和bin/
文件夹中的文件在本地计算机和 Docker 容器中必须不同。 如果它们重叠,你会得到错误。
要解决该问题,您可以更改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/
文件夹路径。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.