The Node.js Runtime

Overview

The Node.js runtime is the software stack responsible for installing your application's code and its dependencies and running your application. The standard runtime is declared in app.yaml as runtime: nodejs:

runtime: nodejs
env: flex

Runtimes in the flexible environment are built using Docker. The Node.js runtime is based on Debian Jessie, and the source code for the Node.js runtime is publicly available on GitHub.

Engines

The default Node.js engine aims to be the latest LTS release. You can specify a different Node.js version in your application's package.json file by using the engines field.

The following example configures the runtime to use the latest Node 8 release.

{
  "engines": {
    "node": "8.x"
  }
}

The engines.node property can be a semver range. If you specify this, the runtime download and installs the latest version of Node.js that matches the semver range. If no match is found, the application will fail to deploy and the runtime will return an error message.

Dependencies

During deployment, the runtime can use either npm or yarn to fetch and install the dependencies declared in your package.json file. By default the runtime uses npm install, but if a yarn.lock file is present, the runtime will use yarn install instead. If you want to force the runtime to use npm, you can list the yarn.lock file in the skip_files section of your app.yaml file.

For more information about managing Node.js packages on Google App Engine, see Using Node.js Libraries.

To enable the use of Node.js packages that require native extensions, the following Debian packages are pre-installed in the Docker image.

If your application requires additional operating-system-level dependencies, you will need to use a custom runtime based on this runtime to install the appropriate packages.

Application startup

The runtime starts your application by using npm start, which uses the command specified in package.json. For example:

"scripts": {
  "start": "node app.js"
}

Your start script should start a web server that responds to HTTP requests on the port specified by the PORT environment variable, typically 8080.

Extending the runtime

The standard Node.js runtime can be used to create a custom runtime. To do this, use gcloud beta app gen-config --custom to create the base Dockerfile and .dockerignore files. You can then customize these files as needed. Note that if you create Dockerfile, you must specify runtime: custom instead of runtime: nodejs in your app.yaml file.

HTTPS and forwarding proxies

App Engine terminates the HTTPS connection at the load balancer and forwards the request to your application. Some applications need to determine the original request IP and protocol. The user's IP address is available in the standard X-Forwarded-For header as well as the X-Appengine-User-Ip header. Applications that require this information should configure their web framework to trust the proxy. With Express.js you would use the trust_proxy setting:

app.set('trust proxy', true);

Environment variables

The following environment variables are set by the runtime environment:

Environment variable Description
GAE_INSTANCE The name of the current instance.
GAE_MEMORY_MB The amount of memory available to the application process.
GAE_SERVICE The service name specified in your application's app.yaml file, or if no service name is specified, it is set to default.
GAE_VERSION The version label of the current application.
GCLOUD_PROJECT The Project ID associated with your application, which is visible in the Google Cloud Platform Console
NODE_ENV When your app is deployed, the value is production.
PORT The port that will receive HTTP requests. Set to 8080.

You can set additional environment variables with app.yaml.

Metadata server

Each instance of your application can use the Compute Engine metadata server to query information about the instance, including its host name, external IP address, instance ID, custom metadata, and service account information. App Engine does not allow you to set custom metadata for each instance, but you can set project-wide custom metadata and read it from your App Engine and Compute Engine instances.

This example function uses the metadata server to get the external IP address of the instance:

const express = require('express');
const request = require('got');

const app = express();
app.enable('trust proxy');

const METADATA_NETWORK_INTERFACE_URL = 'http://metadata/computeMetadata/v1/' +
'/instance/network-interfaces/0/access-configs/0/external-ip';

function getExternalIp () {
  const options = {
    headers: {
      'Metadata-Flavor': 'Google'
    },
    json: true
  };

  return request(METADATA_NETWORK_INTERFACE_URL, options)
    .then((response) => response.body)
    .catch((err) => {
      if (err || err.statusCode !== 200) {
        console.log('Error while talking to metadata server, assuming localhost');
        return 'localhost';
      }
      return Promise.reject(err);
    });
}

app.get('/', (req, res, next) => {
  getExternalIp()
    .then((externalIp) => {
      res.status(200).send(`External IP: ${externalIp}`).end();
    })
    .catch(next);
});

const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
  console.log(`App listening on port ${PORT}`);
  console.log('Press Ctrl+C to quit.');
});

Monitor your resources on the go

Get the Google Cloud Console app to help you manage your projects.

Send feedback about...

App Engine flexible environment for Node.js docs