2
votes

I am creating the azure devops pipeline to build an asp.net web app with react and then create a Docker image. I use below azure-pipeline.yml, and docker file, but I have issue on npm package. Can anybody support me how can I create it: Docker file to restore, build, push and create image:

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
WORKDIR /src
COPY ["./react.csproj", "./"]
RUN dotnet restore "./react.csproj"
COPY . .
WORKDIR "/src/"
RUN dotnet build "react.csproj" -c Release -o /app/build

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

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

azure pipeline to create an image and push it to azure container registry.

pool:
  name: Default

steps:
- task: NuGetToolInstaller@0
  displayName: 'Use NuGet 4.4.1'
  inputs:
    versionSpec: 4.4.1

- task: NuGetCommand@2
  displayName: 'NuGet restore'
  inputs:
    restoreSolution: '$(Parameters.solution)'

- task: DockerCompose@0
  displayName: 'Build services'
  inputs:
    azureSubscription: '$(Parameters.azureSubscriptionEndpoint)'
    azureContainerRegistry: '$(Parameters.azureContainerRegistry)'
    dockerComposeFile: '$(Parameters.dockerComposeFile)'
    dockerComposeFileArgs: 'DOCKER_BUILD_SOURCE='
    action: 'Build services'
    additionalImageTags: '$(Build.BuildId)'
    includeLatestTag: true

- task: DockerCompose@0
  displayName: 'Push services'
  inputs:
    azureSubscription: '$(Parameters.azureSubscriptionEndpoint)'
    azureContainerRegistry: '$(Parameters.azureContainerRegistry)'
    dockerComposeFile: '$(Parameters.dockerComposeFile)'
    additionalDockerComposeFiles: 'docker-compose.ci.yml'
    dockerComposeFileArgs: 'DOCKER_BUILD_SOURCE='
    action: 'Push services'
    additionalImageTags: '$(Build.BuildId)'
    includeLatestTag: true

- task: DockerCompose@0
  displayName: 'Lock services'
  inputs:
    azureSubscription: '$(Parameters.azureSubscriptionEndpoint)'
    azureContainerRegistry: '$(Parameters.azureContainerRegistry)'
    dockerComposeFile: '$(Parameters.dockerComposeFile)'
    additionalDockerComposeFiles: 'docker-compose.ci.yml'
    dockerComposeFileArgs: 'DOCKER_BUILD_SOURCE='
    action: 'Lock services'
    outputDockerComposeFile: '$(Build.ArtifactStagingDirectory)/docker-compose.yml'

- task: CopyFiles@2
  displayName: 'Copy Files to: $(Build.ArtifactStagingDirectory)'
  inputs:
    Contents: |
     **/docker-compose.env.yml
     **/docker-compose.env.*.yml
    TargetFolder: '$(Build.ArtifactStagingDirectory)'

- task: PublishBuildArtifacts@1
  displayName: 'Publish Artifact: docker-compose'
  inputs:
    ArtifactName: 'docker-compose'

You may find the react.csproj here:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
    <TypeScriptToolsVersion>Latest</TypeScriptToolsVersion>
    <IsPackable>false</IsPackable>
    <SpaRoot>ClientApp\</SpaRoot>
    <DefaultItemExcludes>$(DefaultItemExcludes);$(SpaRoot)node_modules\**</DefaultItemExcludes>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="3.1.5" />
  </ItemGroup>

  <ItemGroup>
    <!-- Don't publish the SPA source files, but do show them in the project files list -->
    <Content Remove="$(SpaRoot)**" />
    <None Remove="$(SpaRoot)**" />
    <None Include="$(SpaRoot)**" Exclude="$(SpaRoot)node_modules\**" />
  </ItemGroup>

  <Target Name="DebugEnsureNodeEnv" BeforeTargets="Build" Condition=" '$(Configuration)' == 'Debug' And !Exists('$(SpaRoot)node_modules') ">
    <!-- Ensure Node.js is installed -->
    <Exec Command="node --version" ContinueOnError="true">
      <Output TaskParameter="ExitCode" PropertyName="ErrorCode" />
    </Exec>
    <Error Condition="'$(ErrorCode)' != '0'" Text="Node.js is required to build and run this project. To continue, please install Node.js from https://nodejs.org/, and then restart your command prompt or IDE." />
    <Message Importance="high" Text="Restoring dependencies using 'npm'. This may take several minutes..." />
    <Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
  </Target>

  <Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish">
    <!-- As part of publishing, ensure the JS resources are freshly built in production mode -->
    <Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
    <Exec WorkingDirectory="$(SpaRoot)" Command="npm run build" />

    <!-- Include the newly-built files in the publish output -->
    <ItemGroup>
      <DistFiles Include="$(SpaRoot)build\**" />
      <ResolvedFileToPublish Include="@(DistFiles->'%(FullPath)')" Exclude="@(ResolvedFileToPublish)">
        <RelativePath>%(DistFiles.Identity)</RelativePath>
        <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
        <ExcludeFromSingleFile>true</ExcludeFromSingleFile>
      </ResolvedFileToPublish>
    </ItemGroup>
  </Target>

</Project>
1
Determining projects to restore... All projects are up-to-date for restore. react -> /src/bin/Release/netcoreapp3.1/react.dll my-new-app -> /src/bin/Release/netcoreapp3.1/react.Views.dll /bin/sh: 2: /tmp/tmp0521ff029b114917be8a23c5908b7043.exec.cmd: npm: not found /src/react.csproj(36,5): error MSB3073: The command "npm install" exited with code 127. The command '/bin/sh -c dotnet publish "my-new-app.csproj" -c Release -o /app/publish' returned a non-zero code: 1Meraj Kashi
Can you show what you have in this line ` /src/react.csproj(36,5):`?Krzysztof Madej
Yes, it is added above.Meraj Kashi
Please check if below answer helps to resolve your issue. Feel free to let me know if it's helpful or not~LoLance

1 Answers

1
votes

See Description of code 127.

The error MSB3073: The command "npm install" exited with code 127 indicates that npm install command is not recognized by the system since it's not defined in PATH variable or located in current working directory.

Your image contains dotnet sdk while it doesn't have npm installed so it's expected behavior to get such error.

Workaround:

Modify your Dockerfile like this:

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
RUN curl -sL https://deb.nodesource.com/setup_12.x |  bash -
RUN apt-get install -y nodejs

FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
RUN curl -sL https://deb.nodesource.com/setup_12.x |  bash -
RUN apt-get install -y nodejs
WORKDIR /src
COPY ["./react.csproj", "./"]
RUN dotnet restore "./react.csproj"
COPY . .
WORKDIR "/src/"
RUN dotnet build "react.csproj" -c Release -o /app/build

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

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

You should choose the correct node.js version for your project. For example, change the setup_12.x(Line5 and Line9) to setup_10.x if node.js version 10.x is more suitable for you.

More details about that you can refer to this document.