.NET Core Docker Image for SPA Applications

2020-02-03 13:01发布

What is the correct Docker image to use when creating a new ASP.NET Core MVC app, specifically with the React/Redux (or other Node.js required) template? If not a specific image, what commands or process should be followed in the Dockerfile for a Node.js app backed by ASP.NET Core MVC?

I don't require the SDK version of the framework for anything other than running the backing MVC site.

dotnet new reactredux

The runtime image does not have Node.js installed, and will error when trying to run the container.

Dockerfile:

FROM microsoft/aspnetcore:latest

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

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

Error:

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.

The project I am working with is being upgraded from ASP.NET MVC for .NET Standard 1.1 (standalone), to a new .NET Standard 2.0 React/Redux project.

4条回答
The star\"
2楼-- · 2020-02-03 13:11

The problem is that the base image in your dockerfile (microsoft/aspnetcore:latest) does not have node installed.

So you have to install node so you can run the project. This is the dockerfile I came up with:

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

Notice how on line 5 of the dockerfile I'm running a command to update apt-get. And then in line 8-9 node is installed to the docker image

There is still a problem, hot module replacement from webpack does not work. Not even a full refresh works. I'm still looking in to it.

UPDATE: so I looked into the hot module replacement problem, and it appears to be a limitation of docker for windows.

The workaround is to configure webpack so it can tell the browser to poll for changes on a determined amount of time. See this link to see how to configure it

UPDATE: Doing a little more research I found out that microsoft has an image you can use to build your project, it is called: microsoft/aspnetcore-build. This image has all the dependencies you need for building (including nodejs).

So at the end, what I did was leave my Dockerfile as it was (with microsoft/aspnetcore:2.0 as base image), and created a new Dockerfile for development which references the build image I mentioned before. With the help of docker compose I switch Dockerfiles depending on the environment.

This approach seems more convenient because when images are deployed to production environment they should have all its javascript code ready (in the case of a spa application with angular 2, react, etc), in other words they should not have a nodejs dependency, making them less heavy in size.

查看更多
太酷不给撩
3楼-- · 2020-02-03 13:14

Based on @Daniels answer above, running Visual Studio 2017 v15.4 and ASP.NET Core 2.0 on Docker, here are the changes you need to make to allow correct Production and Development behavior for SPA applications (in my case I'm using Angular):

  • Add a new Dockerfile to your project which is a copy of the original. Lets call it Dockerfile.Development. Modify as follows:

    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"]
    
  • Modify the docker-compose.override.yml file in your solution to use this new dockerfile in development. It'll look something like this:

    version: '3'
    
    services:
      myservice:
        environment:
          - ASPNETCORE_ENVIRONMENT=Development
        ports:
          - "80"
        build:
          dockerfile: Dockerfile.Development
    
  • Modify the webpack.config.js file in your project to enable watching for changes, as follows:

    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 ? [
    
查看更多
我想做一个坏孩纸
4楼-- · 2020-02-03 13:24

I got the Angular example template to work simply by installing nodejs into the base:

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

Everything else (Webpack Hot swap) didn't throw an error.

查看更多
爷的心禁止访问
5楼-- · 2020-02-03 13:36

If you need to add just the node binary to your image you can copy what the microsoft/aspnetcore-build dockerfile does:

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

This adds about ~42 MB to your image vs ~157 MB using apt-get.

查看更多
登录 后发表回答