【问题标题】:.NET Core Docker Image for SPA Applications用于 SPA 应用程序的 .NET Core Docker 映像
【发布时间】:2018-01-23 19:37:29
【问题描述】:

在创建新的 ASP.NET Core MVC 应用程序时使用什么正确的 Docker 映像,特别是使用 React/Redux(或其他需要的 Node.js)模板?如果不是特定的图像,对于由 ASP.NET Core MVC 支持的 Node.js 应用程序,Dockerfile 中应遵循哪些命令或过程?

除了运行支持 MVC 站点之外,我不需要框架的 SDK 版本。

dotnet new reactredux

运行时镜像没有安装Node.js,尝试运行容器时会报错。

Dockerfile:

FROM microsoft/aspnetcore:latest

ARG source=./bin/Debug/netcoreapp2.0/publish/
WORKDIR /app
COPY $source .

EXPOSE 80
ENTRYPOINT ["dotnet", "Project.dll"]

错误:

Unhandled Exception: System.AggregateException: One or more errors occurred. (Failed to start Node process. To resolve this:.

[1] Ensure that Node.js is installed and can be found in one of the PATH directories.
    Current PATH enviroment variable is: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    Make sure the Node executable is in one of those directories, or update your PATH.

我正在处理的项目正在从 ASP.NET MVC for .NET Standard 1.1(独立)升级到新的 .NET Standard 2.0 React/Redux 项目。

【问题讨论】:

  • 我假设您的 API 有一个 .NET Core 后端,并且 index.html 由 Express 之类的 Node 服务提供服务?
  • 更好的方法是为每个容器(Node.js 和 ASP.NET Core)启动 2 个容器,并让它们通过 docker 网络进行通信。
  • @Brad 是的,但为了示例,我使用了dotnet new reactredux 模板,它创建了一个 ASP.NET MVC 应用程序,其中默认路由为 React 应用程序提供服务。
  • @JanshairKhan 同意,但我想通过 dotnet new template 让它“开箱即用”运行。
  • 答案被标记为重复,但我发现它对解决这个问题更有帮助,而这里的答案让我感到困惑:stackoverflow.com/questions/45880460/…

标签: node.js docker asp.net-core asp.net-core-mvc .net-core


【解决方案1】:

这里是容器化 SPA 应用程序的简单方法:

首先,我们必须在应用程序的 csproj 文件中注释这两行,因为它迫使我们将 NodeJS 安装在 docker 容器中。

<Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
<Exec WorkingDirectory="$(SpaRoot)" Command="npm run build" />

接下来,在容器内部,您只需要 ASP.NET Core 运行时即可运行您的应用程序。然而,Node Docker 映像用于编译 React 客户端应用程序。所以你需要一个像这样的 Dockerfile:

FROM node as build-node
WORKDIR /ClientApp
# ClientApp folder contains all your react code
COPY MyApp/ClientApp/package.json .
COPY MyApp/ClientApp/package-lock.json .
RUN npm install
COPY MyApp/ClientApp/ . 
# This command will generate build folder
RUN npm run build

FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
WORKDIR /app
ENV ASPNETCORE_ENVIRONMENT=Production
COPY *.sln .

# In next step you'll get an error if you didn't comment two lines mentioned above in csproj file
COPY MyApp/MyApp.csproj ./MyApp 
RUN dotnet restore
COPY MyApp/. ./MyApp
WORKDIR /app/MyApp
RUN dotnet publish -c Release -o out

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 AS runtime
WORKDIR /app

# Here we get compile result from .net core application
COPY --from=build /app/MyApp/out ./

# Here we  get compile result for React app
COPY --from=build-node /ClientApp/build ./ClientApp/build

# Application port
EXPOSE 5000
ENTRYPOINT ["dotnet", "MyApp.dll"]

【讨论】:

    【解决方案2】:

    即使您运行的是 ASP.NET Core 3.0,来自 Microsoft 的基础镜像仍然不包含 NodeJS。您必须自己安装 NodeJS。幸运的是,这并不那么难。

    这是我最近解决的方法。请注意 Dockerfile 更像是伪代码而不是功能齐全,我去除了大部分噪音。它正在安装 NodeJS 的第 10 版,您当然可以更改它。 Here are different node distributions you can install.

    FROM mcr.microsoft.com/dotnet/core/aspnet:3.0-buster-slim AS base
    WORKDIR /app
    
    FROM mcr.microsoft.com/dotnet/core/sdk:3.0-buster AS build
    
    # Install NodeJS 10
    RUN curl -sL https://deb.nodesource.com/setup_10.x | bash -
    RUN apt-get install -y nodejs
    
    RUN npm install
    RUN npm run test-docker
    RUN npm run build
    
    RUN dotnet restore...
    
    RUN dotnet test...
    
    FROM build AS publish
    RUN dotnet publish "Collector.Forms.Autogiro.Web.csproj" -c Release -o /app/publish
    
    FROM base AS final
    WORKDIR /app
    COPY --from=publish /app/publish .
    ENTRYPOINT ["dotnet", "Your.Web.dll"]
    

    【讨论】:

      【解决方案3】:

      我只需将 nodejs 安装到基础中即可使用 Angular 示例模板:

      FROM microsoft/aspnetcore:2.0 AS base
      RUN apt-get update && \
          apt-get install -y wget && \
          apt-get install -y gnupg2 && \
          wget -qO- https://deb.nodesource.com/setup_6.x | bash - && \
          apt-get install -y build-essential nodejs
      WORKDIR /app
      EXPOSE 80
      ... rest of Dockerfile ...
      

      其他一切(Webpack 热交换)都没有抛出错误。

      【讨论】:

        【解决方案4】:

        根据上面的@Daniels 回答,在 Docker 上运行 Visual Studio 2017 v15.4 和 ASP.NET Core 2.0,您需要进行以下更改以允许 SPA 应用程序的正确生产和开发行为(在我的情况下,我是m 使用 Angular):

        • 向您的项目添加一个新的 Dockerfile,它是原始文件的副本。让我们称之为 Dockerfile.Development。修改如下:

          FROM microsoft/aspnetcore:2.0
          ARG source
          
          # BEGIN MODIFICATION - Node is needed for development (but not production)
          RUN curl -sL https://deb.nodesource.com/setup_6.x | bash -
          RUN apt-get install --assume-yes nodejs
          # END MODIFICATION
          
          WORKDIR /app
          EXPOSE 80
          COPY ${source:-obj/Docker/publish} .
          ENTRYPOINT ["dotnet", "MyService.dll"]
          
        • 修改解决方案中的 docker-compose.override.yml 文件以在开发中使用这个新的 dockerfile。它看起来像这样:

          version: '3'
          
          services:
            myservice:
              environment:
                - ASPNETCORE_ENVIRONMENT=Development
              ports:
                - "80"
              build:
                dockerfile: Dockerfile.Development
          
        • 修改项目中的 webpack.config.js 文件以启用监视更改,如下所示:

          const clientBundleConfig = merge(sharedConfig, {
            entry: { 'main-client': './ClientApp/boot.browser.ts' },
            output: { path: path.join(__dirname, clientBundleOutputDir) },
            // BEGIN MODIFICATION
            watch: isDevBuild,
            watchOptions: {
              poll: isDevBuild ? 1000 : false
            },
            // END MODIFICATION
            plugins: [
              new webpack.DllReferencePlugin({
                  context: __dirname,
                  manifest: require('./wwwroot/dist/vendor-manifest.json')
              })
            ].concat(isDevBuild ? [
          

        【讨论】:

        • 如果您重新阅读他的回答,您会注意到使用 microsoft/aspnetcore-build 进行开发的建议,因此您无需在 dev Dockerfile 中安装 nodejs。
        • 你对 Startup.cs 中的 UseWebpackDevMiddleware() 调用做了什么?即使修改了 webpack.config.js 文件,我也会遇到同样的错误。
        • @ChrisHaines microsoft/aspnetcore-build 已弃用。
        【解决方案5】:

        问题是您的 dockerfile (microsoft/aspnetcore:latest) 中的基础映像没有安装节点。

        所以你必须安装节点才能运行项目。这是我想出的dockerfile:

        FROM microsoft/aspnetcore:2.0
        ARG source
        EXPOSE 80 5102
        ENV ASPNETCORE_URLS http://*:80
        RUN apt-get -qq update && apt-get -qqy --no-install-recommends install wget gnupg \
            git \
            unzip
        
        RUN curl -sL https://deb.nodesource.com/setup_6.x |  bash -
        RUN apt-get install -y nodejs
        WORKDIR /app
        COPY ${source:-obj/Docker/publish} .
        ENTRYPOINT ["dotnet", "Project.dll"]
        

        请注意我在 dockerfile 的第 5 行如何运行命令来更新 apt-get。然后在第 8-9 行将节点安装到 docker 映像中

        还有一个问题,从 webpack 热模块替换不起作用。甚至没有完全刷新工作。我还在研究中。

        更新: 于是查了一下热模块更换问题,貌似是limitation of docker for windows

        解决方法是配置 webpack,以便它可以告诉浏览器在确定的时间内轮询更改。 See this link to see how to configure it

        更新: 再做一些研究,我发现 microsoft 有一个可以用来构建项目的映像,它被称为:microsoft/aspnetcore-build。此镜像包含构建所需的所有依赖项(包括 nodejs)。

        所以最后,我所做的就是让我的 Dockerfile 保持原样(使用 microsoft/aspnetcore:2.0 作为基础映像),并创建一个新的 Dockerfile 用于开发,它引用了我之前提到的构建映像。在 docker compose 的帮助下,我根据环境切换 Dockerfile。

        这种方法似乎更方便,因为当图像部署到生产环境时,它们应该准备好所有的 javascript 代码(对于带有 angular 2、react 等的 spa 应用程序),换句话说,它们不应该有 nodejs依赖性,使它们的体积更小。

        【讨论】:

        • 酷,所以通过 apt-get 包含它是接下来的路要走。谢谢!
        • 谢谢!可以分享文件在Dockerfiles之间切换吗?
        • microsoft/aspnetcore-build 不包含最新版本的 SDK,我使用的是 2.2 版本,我得到了同样的错误。
        • 请注意,microsoft/aspnetcore-build 已成为 officially deprecated。请参阅 2.1 及更高版本的迁移步骤:github.com/aspnet/aspnet-docker/tree/master/2.1
        【解决方案6】:

        如果您只需要将 node 二进制文件添加到您的映像中,您可以复制 microsoft/aspnetcore-build dockerfile 的功能:

        ENV NODE_VERSION 6.10.3
        
        RUN set -ex \
          && for key in \
            9554F04D7259F04124DE6B476D5A82AC7E37093B \
            94AE36675C464D64BAFA68DD7434390BDBE9B9C5 \
            0034A06D9D9B0064CE8ADF6BF1747F4AD2306D93 \
            FD3A5288F042B6850C66B31F09FE44734EB7990E \
            71DCFD284A79C3B38668286BC97EC7A07EDE3FC1 \
            DD8F2338BAE7501E3DD5AC78C273792F7D83545D \
            B9AE9905FFD7803F25714661B63B535A4C206CA9 \
            C4F0DFFF4E8C1A8236409D08E73BC641CC11F4C8 \
          ; do \
            gpg --keyserver pgp.mit.edu --recv-keys "$key" || \
            gpg --keyserver ha.pool.sks-keyservers.net --recv-keys "$key" || \
            gpg --keyserver keyserver.pgp.com --recv-keys "$key" ; \
          done
        
        # set up node
        RUN buildDeps='xz-utils' \
            && set -x \
            && apt-get update && apt-get install -y $buildDeps --no-install-recommends \
            && rm -rf /var/lib/apt/lists/* \
            && curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz" \
            && curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc" \
            && gpg --batch --decrypt --output SHASUMS256.txt SHASUMS256.txt.asc \
            && grep " node-v$NODE_VERSION-linux-x64.tar.xz\$" SHASUMS256.txt | sha256sum -c - \
            && tar -xJf "node-v$NODE_VERSION-linux-x64.tar.xz" -C /usr/local --strip-components=1 \
            && rm "node-v$NODE_VERSION-linux-x64.tar.xz" SHASUMS256.txt.asc SHASUMS256.txt \
            && apt-get purge -y --auto-remove $buildDeps \
            && ln -s /usr/local/bin/node /usr/local/bin/nodejs
        

        这会使您的图像增加约 42 MB,而使用 apt-get 则增加约 157 MB。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-12-12
          • 1970-01-01
          • 2021-10-26
          • 2020-12-16
          • 2019-07-28
          • 1970-01-01
          • 1970-01-01
          • 2022-11-02
          相关资源
          最近更新 更多