node.jsgoogle-app-enginegoogle-cloud-platformgoogle-cloud-buildapp-engine-flexible

Specifying Node.js version for Google Cloud App Engine Flexible


I'm trying to deploy a GCloud App Engine Flexible service. I have a yaml file, in which it has the Node.js runtime and the env specified.

runtime: nodejs
env: flex

As the documentation says "You can specify a different Node.js version in your application's package.json file by using the engines field.", I also added the following to package.json:

"name": "@bindr/dev",
"version": "1.0.0",
"engines": {
  "node": ">=14.0.0"
},

However, when I run gcloud app deploy, I get the following error:

error @bindr/dev@1.0.0: The engine "node" is incompatible with this module. Expected version ">=14.0.0". Got "12.19.0"

It seems like the deployment process doesn't take the engines property into account, because even if I specify an invalid version (e.g. >=18.0.0) it still doesn't complain, only the yarn install fails. How can I make the build process use the specified Node version?

I found that I could specify the version of Node in cloudbuild.yaml for the certain steps of the build, like so:

steps:
  - name: node:node-14.10.0
    args: ['predeploy.js', 'content-server']
  - name: 'gcr.io/cloud-builders/yarn:node-14.17.1'
    args: ['install']
  - name: 'gcr.io/cloud-builders/gcloud'
    args: ['app', 'deploy']
timeout: '900s'

In this process, the yarn install step succeeds, but the gcloud app deploy step still fails while trying to install the dependencies (I couldn't find how I could specify the node version to gcr.io/cloud-builders/gcloud, it doesn't seem to be such tag).

I also checked and the same 12.19.0 version is running on the production instances, so it is not only the build environment that has an older version.

What am I doing wrong?


Solution

  • I encountered the same issue and created an issue for it here. I suspect it is a bug with Google App Engine and not with your app.

    As a workaround, I ended up using a custom runtime for my app. To do this, in your GAE configuration file you switch from runtime: nodejs to runtime: custom and add a Dockerfile to your project root. There are good docs on writing a dockerfile here but here is a simple one you can use:

    # syntax=docker/dockerfile:1
    
    FROM node:14.10.0
    ENV NODE_ENV=production
    
    WORKDIR /app
    
    COPY ["package.json", "package-lock.json*", "./"]
    
    RUN npm install --production
    
    COPY . .
    
    CMD [ "node", "server.js" ]
    

    You'll probably also want a .dockerignore file that at least contains node_modules.

    Ultimately I think a GAE fix would be nicer, since it would be simpler to just configure your node version in package.json, like you're supposed to be able to. But this should be enough to get things working and sidestep what appears to be a GAE bug.