ASP.NET Core 2.0 - 多项目解决方案的Docker文件

73

[asp.net core 2.0和docker的Linux版本]

我对docker完全不熟悉,正试图弄清楚如何在一个包含2个项目的解决方案中使用docker。所有我看过的教程都只是针对单一项目的。

所以如果有人能够提供逐步解决方案,我会非常感激。

我的解决方案结构如下:

Solution.sln
|______WebAPIProject.csproj
|______ClassLibraryProject.csproj

在Visual Studio中,我已经为解决方案添加了Docker支持,并获得了这些文件:

在WebAPIProject下,它创建了这个Docker文件

FROM microsoft/aspnetcore:2.0
ARG source
WORKDIR /app
EXPOSE 80
COPY ${source:-obj/Docker/publish} .
ENTRYPOINT ["dotnet", "WebAPIProject.dll"]

接下来,在单独的docker-compose 'project'下,我有:

docker-compose.ci.build.yml

version: '3'

services:
  ci-build:
    image: microsoft/aspnetcore-build:1.0-2.0
    volumes:
      - .:/src
    working_dir: /src
    command: /bin/bash -c "dotnet restore ./Solution.sln && dotnet publish ./Solution.sln -c Release -o ./obj/Docker/publish"

以及 docker.compose.yml 文件

version: '3'

services:
  WebAPIProject:
    image: WebAPIProject
    build:
      context: ./WebAPIProject
      dockerfile: Dockerfile

我相信这只是路径方面的小问题,但我对此感到非常迷惑,如果有人能够为我解答一下就好了。


1
你好,你找到解决方案了吗? 对我来说,添加Docker支持时会出现错误,当它尝试创建镜像时。谢谢。 - Norcino
7个回答

51

虽然我知道dotnet core不仅限于Windows,也不是每个人都会使用Visual Studio,但Microsoft在Visual Studio中(我在2017年尝试过)包含了一个很棒的功能。

  1. 右键单击Web项目。
  2. 选择添加。
  3. 然后选择“Docker Support”。这将自动将多个项目取回到容器中。

如果您有多个Web项目,请为每个项目重复此步骤。

这里是参考:https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/docker/visual-studio-tools-for-docker?view=aspnetcore-2.1#existing-app

如果在运行Docker容器时遇到任何问题,请尝试在“Windows功能”中取消选择Hyper-V Services(在开始菜单中搜索Windows Features),重新选择,然后重新启动计算机。 请查看此处

输入图像描述


很不幸,当我使用这个命令时,我遇到了一个类似于这个问题的错误 - https://github.com/docker/for-mac/issues/1922 - cah1r
1
禁用 Hyper-V 功能对我有用。谢谢! - Eugen Zaharia
4
这是一个救命的小贴士。我为此问题挣扎了两天,非常感谢。 - Gerson C Filho
我不得不将Dockerfile拖放到包含.sln的同一文件夹中。谢谢! - Christophe Chenel
类库缺少该选项。 :-/ - BrainSlugs83

49
我终于找到了使用docker构建解决方案的方法。 重要提示:为使此方法生效,您需要将Dockerfile文件放在与解决方案文件相同的位置。 我刚刚创建了一个具有以下内容的docker文件:
FROM microsoft/aspnetcore:2.0 AS base
WORKDIR /app
EXPOSE 80

FROM microsoft/aspnetcore-build:2.0 AS build
WORKDIR /src
COPY Solution.sln ./
COPY ClassLibraryProject/*.csproj ./ClassLibraryProject/
COPY WebAPIProject/*.csproj ./WebAPIProject/

RUN dotnet restore
COPY . .
WORKDIR /src/ClassLibraryProject
RUN dotnet build -c Release -o /app

WORKDIR /src/WebAPIProject
RUN dotnet build -c Release -o /app

FROM build AS publish
RUN dotnet publish -c Release -o /app

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

请注意,我认为您可能需要尊重项目构建依赖关系,但我不太确定。
构建的示例调用:
sudo docker build --no-cache -t webapi:dev .

运行示例调用:

sudo docker run -d=false -p 8080:80 --name webapi webapi:dev

希望这能帮到你。

在 Docker 构建时,我遇到了这个错误 COPY failed: stat /var/lib/docker/tmp/docker-builder953792128/MyProject.sln: no such file or directory,有什么建议吗? - rootcoder
Dockerfile和解决方案文件是否在同一个文件夹中? - Rod
不,它是这样的 project1.sln,project1文件夹 -> Dockerfile,project1.csproj - rootcoder
3
这就是为什么Docker找不到您的sln文件的原因。从Docker文件位置看,路径是相对的。请将Docker文件复制到解决方案文件夹中,这样就可以了。 - Rod
如果我将Docker文件移动到解决方案文件夹中,那么从Visual Studio构建和发布就会失败。这是一个糟糕的解决方案。 - BrainSlugs83

46

我曾经遇到相同的问题,但所有其他解决方案都不适合我,因此我制定了自己的解决方案。我觉得下面的步骤很合理,但如果你是Docker新手,我在我的博客文章中专门为新用户讲解(这样你可以精确地理解在这个中正在发生什么)。

  1. 将保留在项目目录中(在我看来,这比将它放在解决方案文件旁边更好,因为您可以拥有解决方案中的多个Docker映像)。

  2. 按以下方式配置:

FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build-env
WORKDIR /app

COPY . ./
RUN dotnet publish PROJECT_NAME -c Release -o out

FROM mcr.microsoft.com/dotnet/core/aspnet:2.2
WORKDIR /app
COPY --from=build-env /app/PROJECT_NAME/out .

ENTRYPOINT ["dotnet", "PROJECT_NAME.dll"]
  1. .dockerignore 文件移动到解决方案目录中 - 这是必需的,因为 Docker CLI 只从构建上下文的根目录中获取 .dockerignore 文件(正如文档所述),但这也很方便,因为您可以为所有项目拥有一个通用的忽略规则集合(类似于 .gitignore 文件),这样更容易维护。

  2. 从解决方案目录中运行构建命令,指向项目目录中的 Dockerfile ,并将当前目录 (.) 设置为构建上下文(以便访问所有项目):

docker build -f PROJECT_DIRECTORY/Dockerfile -t IMAGE_NAME .
  • 像往常一样运行容器,例如:
  • docker run -d -p 8080:80 --name my-app-name IMAGE_NAME
    

    6
    第四点正是我所需要的!谢谢!对于我的情况,我是通过VS的“添加Docker支持”来生成dockerfile的。之后,我只需从我的解决方案目录中执行docker build命令,指向目标项目的Dockerfile路径即可。 - DriLLFreAK100
    1
    Tometchy,你真是个天才,谢谢你的解决方案。我已经尝试过了,它找到了其他的csproj文件,谢谢! - MFARKAN

    15

    这是链接到一篇关于如何解决这个问题的惊人文章an amazing post.

    他提到要将所有代码放入src目录中。我没有这样做,以下是我写出的文件:(关键是for file部分。否则,这可能不是最好的dockerfile; 欢迎分享提示。)

    FROM microsoft/dotnet:2.2-aspnetcore-runtime-stretch-slim AS base
    WORKDIR /app
    EXPOSE 5000
    
    FROM microsoft/dotnet:2.2-sdk-stretch AS build
    WORKDIR /src
    
    COPY ./*.sln ./
    
    COPY */*.csproj ./
    RUN for file in $(ls *.csproj); do mkdir -p ${file%.*} && mv $file ${file%.*}; done
    RUN dotnet restore
    
    COPY . ./
    RUN dotnet build -c Release -o /app
    
    FROM build AS publish
    RUN dotnet publish -c Release -o /app
    
    FROM base AS final
    WORKDIR /app
    COPY --from=publish /app .
    
    ENV ASPNETCORE_URLS="http://*:5000"
    ENTRYPOINT ["dotnet", "PersonalSiteApi.dll"]
    

    4

    从2022年开始,docker-compose 3.9版本如下

    尝试了几次后,我终于以以下方式完成了它:

    项目层级结构:

    MoulaTracker/
    |- MoulaTracker.Core/    # <- PROJECT 1
    |- MoulaTracker.Api/     # <- PROJECT 2
    |- Dockerfile.Core
    |- Dockerfile.Api
    |- docker-compose.yml
    |- MoulaTracker.sln
    

    项目MoulaTracker.Api依赖于MoulaTracker.Core

    docker-compose.yml:

    version: "3.9"
    
    services:
      moula-tracker-core:
        build:
          context: .
          dockerfile: ./Dockerfile.Core
      moula-tracker-api:
        build:
          context: .
          dockerfile: ./Dockerfile.Api
    

    Dockerfile.Api:

    FROM mcr.microsoft.com/dotnet/core/sdk:3.1.409 AS build-env
    
    # Copy csproj and restore as distinct layers
    WORKDIR /MoulaTracker.Api
    COPY ./MoulaTracker.Api .
    COPY ./MoulaTracker.Core ../MoulaTracker.Core
    RUN dotnet restore
    
    RUN dotnet publish -c Release -o out
    
    # Build runtime image
    FROM mcr.microsoft.com/dotnet/core/aspnet:3.1.0 AS runtime
    
    WORKDIR /MoulaTracker.Api
    COPY --from=build-env /MoulaTracker.Api/ ./
    
    ENTRYPOINT ["dotnet", "out/MoulaTracker.Api.dll"]
    

    2
    FROM microsoft/dotnet:sdk AS build-env
    WORKDIR /app
    
    RUN mkdir /output
    
    # Copy project and publish
    
    COPY . /app
    
    WORKDIR /app/YourProjectName
    RUN dotnet publish --configuration Debug --output /output
    
    # Build runtime image
    FROM microsoft/dotnet:aspnetcore-runtime
    
    ENV ASPNETCORE_URLS http://*:5001
    
    WORKDIR /app
    
    COPY --from=build-env /output .
    EXPOSE 5001
    
    ENTRYPOINT ["dotnet", "YourProjectName.dll"]
    

    这是我使用的Docker配置。这是一个带有许多子项目引用的ASP.NET Core 2 WebApi项目。"Original Answer"翻译成"最初的回答"。
    Then run it using  docker run -d -p 8080:5001 --name some-name yourpojectname
    

    希望这能帮到有需要的人。最初的回答。

    0
    1. 以管理员身份安装Docker桌面版
    2. 以管理员身份运行Docker桌面版
    3. 将您的sln文件移动到项目文件夹(项目文件夹级别)
    4. 右键单击项目,选择添加选项 -> Docker支持 -> 容器编排支持,并选择Linux操作系统,然后单击确定
    5. 它将生成DockerFile和docker composer文件
    6. 以管理员身份打开命令提示符并转到sln文件路径
    7. 运行docker-compose build
    8. 在docker-compose up之后

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接