GoogleCloudPlatform/buildpacks

Angular SSR application deployment failing

LukeSchlangen opened this issue · 1 comments

Describe the bug
I'm trying to deploy an Angular SSR application to Cloud Run using Buildpacks. The build is successful, but the deployment is failing with the error:

> ng serve
ng: not found

Additional context
How are you using GCP buildpacks?

  • pack and the gcr.io/buildpacks/builder
  • Cloud Functions
  • Cloud Run
  • Cloud Build
  • App Engine Standard
  • App Engine Flex

Did this used to work?
No

What language is your project primarily written in?
Node.js, Angular

Steps To Reproduce
Steps to reproduce the behavior:

  1. npm install -g @angular/cli
  2. ng new --ssr my-angular-app
  3. cd my-angular-app
  4. gcloud run deploy

Expected behavior
A successful deployment.

I'm not an expert in what Buildpacks are capable of, but my recommendation is:

  1. Continue to try to run npm start (to prevent a breaking change)
  2. If npm start fails with the message ng: not found after attempting ng serve, attempt to find and run the script starting with serve:ssr:

Actual behavior

The current npm start command for angular runs ng serve, typically, this runs the development server. That is currently failing. Instead of forcing it to work, in production, it would be even better if it ran the script "serve:ssr:my-angular-app": "node dist/my-angular-app/server/server.mjs" (where my-angular-app is the name of the application).

I did test changing the start script to node dist/my-angular-app/server/server.mjs and the site deployed correctly (in production mode).

Example:

This deployment fails:

  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "serve:ssr:my-angular-app": "node dist/my-angular-app/server/server.mjs"
  },

This deployment succeeds:

  "scripts": {
    "ng": "ng",
    "start": "node dist/my-angular-app/server/server.mjs",
    "build": "ng build"
  },

Spent some time investigating this, and I think the issue is in our logic for determining the default entry point for node applications in the npm buildpack: https://github.com/GoogleCloudPlatform/buildpacks/blob/main/pkg/nodejs/npm.go#L208

Summary is that angular apps have start script the relys on ng CLI, but the ng CLI is a devDependency which gets pruned out of the final application image. This is actually expected, as angular apps have a serve:ssr:<app-name> script that should actually be used to start the application in prod.