Docker и asp.net core 3.1 + angular application

Пытаюсь впервые развернуть приложение в докере. При создании приложения выбрал шаблон Angular application.

Вот мой Dockerfile:

 # escape=`

ARG NODE_IMAGE=node:10.16.0

FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
WORKDIR /src
COPY ["DbFirstProj/DbFirstProj.csproj", "DbFirstProj/"]
RUN dotnet restore "DbFirstProj/DbFirstProj.csproj"
COPY . .
WORKDIR "/src/DbFirstProj"
RUN dotnet build "DbFirstProj.csproj" -c Release -o /app
RUN dotnet publish "DbFirstProj.csproj" -c Release -o /app

COPY --from=downloadnodejs C:\Program Files\nodejs\ C:\Windows\system32\

FROM ${NODE_IMAGE} as node-build
WORKDIR /src
COPY DbFirstProj/ClientApp .
RUN npm install
RUN npm rebuild node-sass
RUN npm run build -- --prod
COPY --from=downloadnodejs C:\Program Files\nodejs\ C:\Windows\system32\

FROM mcr.microsoft.com/powershell:nanoserver-1903 AS downloadnodejs
SHELL ["pwsh", "-Command", "$ErrorActionPreference = 'Stop';$ProgressPreference='silentlyContinue';"]
RUN Invoke-WebRequest -OutFile nodejs.zip -UseBasicParsing "https://nodejs.org/dist/v10.16.3/node-v10.16.3-win-x64.zip"; `
  Expand-Archive nodejs.zip -DestinationPath C:\; `
  Rename-Item "C:\node-v10.16.3-win-x64" c:\nodejs

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 AS base
WORKDIR /app
EXPOSE 80
COPY --from=build /app .
COPY --from=node-build /src/dist ./ClientApp/dist
ENTRYPOINT ["dotnet", "DbFirstProj.dll"]

При запуске команды docker build -t arthur12345/dbfirstproj . Получаю след ошибку:

'npm' is not recognized as an internal or external command,
  operable program or batch file.
C:\src\DbFirstProj\DbFirstProj.csproj(55,5): error MSB3073: The command "npm install" exited with code 9009.

Каким образом можно исправить эту ошибку? Возможно изменить мой Dockerfile?


Ответы (1 шт):

Автор решения: Exploding Kitten

Это происходит из-за того, что в шаблоне Angular в csproj файле находятся команды для сборки вашего Angular проекта, которые требуют наличия Node и npm.

Это можно посмотреть внутри csproj после строк:

<Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish">

Также в вашем Startup файле есть такой код, который в дебаг сборке запускает внутренний сервер Angular для хостинга UI:

app.UseSpa(spa =>
{
    spa.Options.SourcePath = "ClientApp";

    if (env.IsDevelopment())
    {
        spa.UseAngularCliServer(npmScript: "start");
    }
});

Исправить это можно добавив Node в Dockerfile, например (версии и имена будут отличаться):

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
# устанавливаем нужную версию NodeJS 15
RUN curl -sL https://deb.nodesource.com/setup_15.x | bash - && \
    apt-get install -y nodejs
WORKDIR /src
COPY ["xxx.csproj", "./"]
RUN dotnet restore "xxx.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "xxx.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "xxx.csproj" -c Release -o /app/publish

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

В результате будет создан образ в котором будет запаковано приложение полностью, и бекэнд и фронт (все будет хоститься внутренним сервером .Net Core).

Также можно разделить на разные контейнеры, чтобы UI собирался отдельно, но это потребует изменения csproj файла.

→ Ссылка