简体   繁体   中英

ASP.NET Core 3.1 Angular Web App builds and runs on Windows but fails on Mac OSX and in Docker

I created a basic ASP.NET Core 3.1 Web app from Angular template in Visual Studio 2019 on a Windows 10 machine. The entire project source code is located here

git clone https://erotavlas-1@bitbucket.org/dev-issues/webclient.git

When I build and run it on Windows machine it works fine and launches correctly inside the Microsoft Edge browser.

However when I copied the project to my Macbook (OS Catalina) and was going to build it into a docker image, it fails to do so. These are the messages at the end of the build

  > webclient@0.0.0 build /src/WebClient/ClientApp
  > ng build "--prod"

  Browserslist: caniuse-lite is outdated. Please run next command `npm update`
  Killed
  npm ERR! code ELIFECYCLE
  npm ERR! errno 137
  npm ERR! webclient@0.0.0 build: `ng build "--prod"`
  npm ERR! Exit status 137
  npm ERR! 
  npm ERR! Failed at the webclient@0.0.0 build script.
  npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

  npm ERR! A complete log of this run can be found in:
  npm ERR!     /root/.npm/_logs/2020-06-12T13_22_34_364Z-debug.log
/src/WebClient/WebClient.csproj(40,5): error MSB3073: The command "npm run build -- --prod" exited with code 137.
The command '/bin/sh -c dotnet publish "WebClient.csproj" -c Release -o /app/publish' returned a non-zero code: 1

Then I thought maybe something was wrong with the project so I tried to open it in Visual Studio for Mac and it builds perfectly fine with no errors. But when I run it it generates the following output in the Visual Studio output

npm ERR! A complete log of this run can be found in:

)
---> System.InvalidOperationException: The NPM script 'start' exited without indicating that the Angular CLI was listening for requests. The error output was: sh: /Users/username/Documents/DEV/WebClient/WebClient/ClientApp/node_modules/.bin/ng: Permission denied

npm ERR! code ELIFECYCLE

npm ERR! errno 126
npm ERR! webclient@0.0.0 start: `ng serve "--port" "59704"`
npm ERR! Exit status 126
npm ERR! 
npm ERR! Failed at the webclient@0.0.0 start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.


npm ERR! A complete log of this run can be found in:


---> System.IO.EndOfStreamException: Attempted to read past the end of the stream.
   at Microsoft.AspNetCore.SpaServices.AngularCli.AngularCliMiddleware.StartAngularCliServerAsync(String sourcePath, String npmScriptName, ILogger logger)
   --- End of inner exception stack trace ---
   at Microsoft.AspNetCore.SpaServices.AngularCli.AngularCliMiddleware.StartAngularCliServerAsync(String sourcePath, String npmScriptName, ILogger logger)
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
   at System.Threading.Tasks.Task`1.get_Result()
   at Microsoft.AspNetCore.SpaServices.AngularCli.AngularCliMiddleware.<>c.<Attach>b__2_0(Task`1 task)
   at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()
   at System.Threading.Tasks.Task.<>c.<.cctor>b__274_0(Object obj)
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location where exception was thrown ---
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
   at System.Threading.Tasks.Task`1.get_Result()
   at Microsoft.AspNetCore.SpaServices.Extensions.Util.TaskTimeoutExtensions.WithTimeout[T](Task`1 task, TimeSpan timeoutDelay, String message)
   at Microsoft.AspNetCore.SpaServices.Extensions.Proxy.SpaProxy.PerformProxyRequest(HttpContext context, HttpClient httpClient, Task`1 baseUriTask, CancellationToken applicationStoppingToken, Boolean proxy404s)
   at Microsoft.AspNetCore.Builder.SpaProxyingExtensions.<>c__DisplayClass2_0.<<UseProxyToSpaDevelopmentServer>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

The Browser opens with the message

An unhandled exception occurred while processing the request.
AggregateException: One or more errors occurred. (One or more errors occurred. (The NPM script 'start' exited without indicating that the Angular CLI was listening for requests. The error output was: sh: /Users/username/Documents/DEV/WebClient/WebClient/ClientApp/node_modules/.bin/ng: Permission denied

npm ERR! code ELIFECYCLE

npm ERR! errno 126
npm ERR! webclient@0.0.0 start: `ng serve "--port" "59704"`
npm ERR! Exit status 126
npm ERR!
npm ERR! Failed at the webclient@0.0.0 start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.


npm ERR! A complete log of this run can be found in:

))

When I tried to build the docker image on Windows it also failed.

Any guidance with this is appreciated.

I did some investigation on this issue using my Mac. Turns out I can build and run the docker container successfully after some modifications. You can check my detailed code changeshere .

I can successfully run it on Mac by running the following commands:

dotnet build
cd WebClient
dotnet run

1. Removing PublishRunWebpack from csproj

When I tried to run the Dockerfile to build the image, I saw the same error as the problem described, which somehow leaded me to this article and checked the PublishRunWebpack task in the WebClient.csproj :

<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 -- --prod" />
  <Exec WorkingDirectory="$(SpaRoot)" Command="npm run build:ssr -- --prod" Condition=" '$(BuildServerSideRenderer)' == 'true' " />

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

The PublishRunWebpack task will run when publishing the app (ie dotnet publish... ) and therefore will not be triggered under development (ie dotnet run ), suggesting that npm run build -- --prod failed when building the Docker image or npm does not even exist in your building stage.

2. Adding build stage in Dockerfile (for node)

Therefore, I removed that build target from WebClient.csproj and added a build stage in Dockerfile to build the Angular web app. The following code segment shows the node build stage only and here is the complete Dockerfile .

### some steps to build and publish the dotnet app...

#Angular build
FROM node as nodebuilder

# set working directory
RUN mkdir /usr/src/app
WORKDIR /usr/src/app

# add `/usr/src/app/node_modules/.bin` to $PATH
ENV PATH /usr/src/app/node_modules/.bin:$PATH

# install and cache app dependencies
COPY WebClient/ClientApp/package.json /usr/src/app/package.json
RUN npm install
# (use 8.3.14 as I saw package.json is using this)
RUN npm install -g @angular/cli@8.3.14 --unsafe

# add app
COPY WebClient/ClientApp/. /usr/src/app

## this is the original step stated in the .csproj file
RUN npm run build -- --prod

## or, you can use the following command if you enable server-side prerendering
# RUN npm run build:ssr -- --prod

### some steps to copy the Angular web app to ClientApp/dist/...

3. Fixing Angular build errors

When I started to build the Docker image again, I met the following issues and got the solutions from Stack Overflow:

Build and run

After that, I can build and run the Docker image successfully at http://localhost:8080:

docker build . -t web-client
docker run -p 8080:80 -d web-client

运行 dockerized 应用程序

The dashboard shows the app is running: 码头工人仪表板

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM