Skip to content

Backgrounds

How-to Guides

Technical References

Node.js on VIP

Use cases of Node.js applications

Two types of Node.js applications are supported on the VIP Platform.

Decoupled / headless frontend

The REST API allows WordPress to operate in a decoupled / headless manner. Rather than a traditional PHP-driven theme, sites can be run as a static single-page application (SPA) or a fully isomorphic application (with server-side rendering).

Both types are supported, and VIP offers some add-ons (like Redis) to make them even more complete.

Microservices / APIs

WordPress is flexible enough to support many different use cases, but not all of them. A companion microservice can be used to offload tasks that may not be well-suited for a typical WordPress app, such as a proxy for another API or service or a middleware layer like a GraphQL API.

Node.js versions

VIP supports all Active LTS or Maintenance LTS releases and the next Active LTS candidate of Node.js. Pinning to non-major versions is not supported and minor upgrades will be applied as soon as they are made available.

Requirements

An application must fulfill several requirements before it is able to run on VIP’s infrastructure:

Requirement 1: Exposing a health-check endpoint

We send periodic health checks (pings) to a specific endpoint: /cache-healthcheck?. If your application doesn’t respond correctly to these requests, our system will flag it as unhealthy and continually restart it. Unhealthy applications will also fail to deploy.

Therefore, your application must provide this endpoint and ensure that it responds with HTTP status code 200. Here’s how to implement this in a few of the most-used frameworks:

Usage with Express

const app = express();

app.get( '/cache-healthcheck?', function ( req, res ) {
  res.sendStatus( 200 );
})

Usage with Next.js

Step 1: Add the following file pages/api/cache-healthcheck.js with the following content:

export default function handler( req, res ) {
	res.status( 200 ).send( 'Ok' );
}

Step 2: Add the following rewrite to the next.config.js to internally route all requests for /cache-healthcheck? to /api/cache-healthcheck:

module.exports = {
  async rewrites() {
    return [
      {
        source: '/cache-healthcheck?',
		destination: '/api/cache-healthcheck',
      },
    ]
  },
}

Requirement 2: Production dependencies and NPM scripts

We use the dependencies and scripts defined in package.json to install, build, and start an application. Make sure all necessary packages needed for an application to run are publicly accessible and are added as dependencies and not devDependencies. Only production dependencies are installed:

npm install --production

The build script allows you to compile your app or perform any necessary tasks before starting it. Even if your app does not require a build step, we still expect this script to be present. Please use "build": "echo 'No build'" or equivalent to fulfill this requirement. The build script is run with NODE_ENV=production and must complete successfully (exit with 0):

NODE_ENV=production npm run build

After a successful build, VIP will start an app using the start script. Not all frameworks supply a start script, so an app may need to define one manually. The start script is run with NODE_ENV=production:

NODE_ENV=production npm start

Requirement 3: Dynamic PORT

We assign a dynamic port to applications using the PORT environment variable. In order for your application to work correctly, it needs to start on the assigned port.

If your application’s port is declared in code, you can access the assigned port using process.env.PORT. You may wish to fall back to a default port if no port is assigned (i.e., in local development):

const PORT = process.env.PORT || 3000;

If your application’s port is defined in the start script in package.json, you can access the assigned port using $PORT:

"start": "frontity serve --port $PORT"

Testing your production build locally

We provide an NPM package that conducts “preflight checks” to verify that the requirements have been met. Run this command in the root of your project:

npx @automattic/vip-go-preflight-checks

Other requirements

Stateless, immutable, and multi-container

All applications on VIP must be able to run across multiple containers and processes at the same time. This means that each deployment of your Node.js application must be stateless and immutable. The file system in the container is read-only and your application must not rely on absolute paths. If any data is stored in memory it will be lost on deployment or when containers are added or removed.

Data can be persisted elsewhere (e.g., in your WordPress application via the REST API or GraphQL). If you need to cache data for later reuse, we offer the ability to deploy Redis alongside the Node.js application.

No process monitors

For production deployment, your application does not need any process monitors (like nodemon or PM2) to handle restarts. This is handled automatically for you.

Example applications that fulfill all these requirements can be found in our Node skeleton starter repository.

Limitations

For security and performance reasons, there are some paths that have special behavior across all applications hosted on VIP, even Node.js applications:

  • /wp-admin
  • /wp-content
  • /wp-includes
  • /wp-login

We recommend avoiding the use of these paths on Node.js sites. If you need to proxy or redirect a request matching one of these paths to a WordPress site, we suggest rewriting it. For example, redirect https://nodejs-app.example.com/admin to https://wp-app.example.com/wp-admin/.

Redis

If you are using Redis, the connection information is supplied to your application via environment variables:

  • VIP_REDIS_PRIMARY: The primary Redis endpoint, represented by an IP address and port separated by a colon. Example: "127.0.0.1:1234".
  • VIP_REDIS_REPLICAS: A comma-separated list of endpoints for Redis replicas. Example: "127.0.0.1:9876,127.0.0.1:5432"
  • VIP_REDIS_PASSWORD The password, which is the same for the primary instance and all replicas.

You can access these variables using process.env (e.g., process.env.VIP_REDIS_PRIMARY). Note that the Redis operations EVAL, EVALSHA, and SCRIPT are disabled by default. Please contact VIP if your application requires these operations.

New Relic

To enable New Relic on VIP Go for the first time, please create a support ticket and we’ll enable it. For more information on New Relic application monitoring and its benefits, see our technical reference page.

Using New Relic with Node.js requires you to install the official NPM package and require / import the package. Once New Relic has been enabled for your application, we will configure the monitoring using environment variables. Do not configure the New Relic agent via newrelic.js.

Last updated: January 06, 2022