--> -->

Node.js is a popular JavaScript runtime built on Chrome’s V8 JavaScript engine. Platform.sh supports deploying Node.js applications quickly and easily. Using our Multi-App support you can build a micro-service oriented system mixing both Javascript and PHP applications.

Supported versions 

Grid Dedicated
  • 6
  • 8
  • 10
  • 12
  • 14
  • 10
  • 12
  • 14

If you need other versions, take a look at our options for installing them with NVM.

Deprecated versions 

Some versions with a minor (such as 8.9) are available but are not receiving security updates from upstream, so their use is not recommended. They will be removed at some point in the future.

Grid Dedicated
  • 0.12
  • 4.7
  • 4.8
  • 6.1
  • 6.9
  • 8.2
  • 9.8

Support libraries 

While it is possible to read the environment directly from your application, it is generally easier and more robust to use the platformsh-config NPM library which handles decoding of service credential information for you.

Configuration 

To use Platform.sh and Node.js together, configure the .platform.app.yaml file with a few key settings, as described here (a complete example is included at the end).

  1. Specify the language of your application (available versions are listed above):

    type: 'nodejs:14'
  2. Specify your dependencies under the nodejs key, like this:

    dependencies:
      nodejs:
        pm2: "^4.5.0"
    

    These are the global dependencies of your project (the ones you would have installed with npm install -g). Here we specify the pm2 process manager that will allow us to run the node process.

  3. Configure the command you use to start serving your application (this must be a foreground-running process) under the web section, e.g.:

    web:
      commands:
        start: "PM2_HOME=/app/run pm2 start index.js --no-daemon"
    

    If there is a package.json file present at the root of your repository, Platform.sh will automatically install the dependencies. We suggest including the platformsh-config helper npm module, which makes it trivial to access the running environment.

    {
      "dependencies": {
        "platformsh-config": "^2.0.0"
      }
    }
    
  4. Create any Read/Write mounts. The root file system is read only. You must explicitly describe writable mounts. In (3) we set the home of the process manager to /app/run so this needs to be writable.

    mounts:
        run:
            source: local
            source_path: run
    
  5. Include any relevant commands needed to build and setup your application in the hooks section, e.g.:

    hooks:
      build: |
        npm install
        npm run build    
    
  6. Setup the routes to your Node.js application in .platform/routes.yaml.

    "https://{default}/":
      type: upstream
      upstream: "app:http"
    
  7. (Optional) If Platform.sh detects a package.json file in your repository, it will automatically include a default build flavor, that will run npm prune --userconfig .npmrc && npm install --userconfig .npmrc. You can modify that process to use an alternative package manager by including the following in your .platform.app.yaml file:

    build:
      flavor: none
    

    Consult the documentation specific to Node.js builds for more information.

Here’s a complete example that also serves static assets (.png from the /public directory):

name: node
type: nodejs:14

web:
  commands:
    start: "PM2_HOME=/app/run pm2 start index.js --no-daemon"
    #in this setup you will find your application stdout and stderr in /app/run/logs
  locations:
    "/public":
      passthru: false
      root: "public"
      # Whether to allow files not matching a rule or not.
      allow: true
      rules:
        '\.png$':
          allow: true
          expires: -1
dependencies:
  nodejs:
    pm2: "^4.5.0"
mounts:
   run:
       source: local
       source_path: run
disk: 512

In your application… 

Finally, make sure your Node.js application is configured to listen over the port given by the environment (here we use the platformsh helper and get it from config.port) that is available in the environment variable PORT. Here’s an example:

// Load the http module to create an http server.
const http = require('http');

// Load the Platform.sh configuration
const config = require('platformsh-config').config();

const server = http.createServer(function (request, response) {
  response.writeHead(200, {"Content-Type": "application/json"});
  response.end(JSON.stringify(config));
});

server.listen(config.port);

Accessing services 

To access various services with Node.js, see the following examples. The individual service pages have more information on configuring each service.

const elasticsearch = require("elasticsearch");
const config = require("platformsh-config").config();

exports.usageExample = async function () {
    const credentials = config.credentials("elasticsearch");

    const client = new elasticsearch.Client({
        host: `${credentials.host}:${credentials.port}`,
    });

    const index = "my_index";
    const type = "People";

    // Index a few document.
    const names = ["Ada Lovelace", "Alonzo Church", "Barbara Liskov"];

    const message = {
        refresh: "wait_for",
        body: names.flatMap((name) => [
            { index: { _index: index, _type: type } },
            { name },
        ]),
    };

    await client.bulk(message);

    // Search for documents.
    const response = await client.search({
        index,
        q: "name:Barbara Liskov",
    });

    const outputRows = response.hits.hits
        .map(
            ({ _id: id, _source: { name } }) =>
                `<tr><td>${id}</td><td>${name}</td></tr>\n`
        )
        .join("\n");

    // Clean up after ourselves.
    await Promise.allSettled(
        response.hits.hits.map(({ _id: id }) =>
            client.delete({
                index: index,
                type: type,
                id,
            })
        )
    );

    return `
    <table>
        <thead>
            <tr>
                <th>ID</th><th>Name</th>
            </tr>
        </thhead>
        <tbody>
            ${outputRows}
        </tbody>
    </table>
    `;
};
const Memcached = require('memcached');
const config = require("platformsh-config").config();
const { promisify } = require('util');

exports.usageExample = async function() {
    const credentials = config.credentials('memcached');
    const client = new Memcached(`${credentials.host}:${credentials.port}`);

    // The MemcacheD client is not Promise-aware, so make it so.
    const memcachedGet = promisify(client.get).bind(client);
    const memcachedSet = promisify(client.set).bind(client);

    const key = 'Deploy-day';
    const value = 'Friday';

    // Set a value.
    await memcachedSet(key, value, 10);

    // Read it back.
    const test = await memcachedGet(key);

    return `Found value <strong>${test}</strong> for key <strong>${key}</strong>.`;
};
const mongodb = require("mongodb");
const config = require("platformsh-config").config();

exports.usageExample = async function () {
    const credentials = config.credentials("mongodb");
    const MongoClient = mongodb.MongoClient;

    const client = await MongoClient.connect(
        config.formattedCredentials("mongodb", "mongodb")
    );

    const db = client.db(credentials["path"]);

    const collection = db.collection("startrek");

    const documents = [
        { name: "James Kirk", rank: "Admiral" },
        { name: "Jean-Luc Picard", rank: "Captain" },
        { name: "Benjamin Sisko", rank: "Prophet" },
        { name: "Katheryn Janeway", rank: "Captain" },
    ];

    await collection.insertMany(documents, { w: 1 });

    const result = await collection.find({ rank: "Captain" }).toArray();

    const outputRows = Object.values(result)
        .map(({ name, rank }) => `<tr><td>${name}</td><td>${rank}</td></tr>\n`)
        .join("\n");

    // Clean up after ourselves.
    collection.deleteMany();

    return `
    <table>
        <thead>
            <tr>
                <th>Name</th><th>Rank</th>
            </tr>
        </thhead>
        <tbody>
            ${outputRows}
        </tbody>
    </table>
    `;
};
const mysql = require("mysql2/promise");
const config = require("platformsh-config").config();

exports.usageExample = async function () {
    const credentials = config.credentials("database");

    const connection = await mysql.createConnection({
        host: credentials.host,
        port: credentials.port,
        user: credentials.username,
        password: credentials.password,
        database: credentials.path,
    });

    // Creating a table.
    await connection.query(
        `CREATE TABLE IF NOT EXISTS People (
            id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
            name VARCHAR(30) NOT NULL,
            city VARCHAR(30) NOT NULL
        )`
    );

    // Insert data.
    await connection.query(
        `INSERT INTO People (name, city)
        VALUES
            ('Neil Armstrong', 'Moon'),
            ('Buzz Aldrin', 'Glen Ridge'),
            ('Sally Ride', 'La Jolla');`
    );

    // Show table.
    const [rows] = await connection.query("SELECT * FROM People");

    // Drop table.
    await connection.query("DROP TABLE People");

    const outputRows = rows
        .map(({ name, city }) => `<tr><td>${name}</td><td>${city}</td></tr>\n`)
        .join("\n");

    return `
    <table>
        <thead>
            <tr>
                <th>Name</th><th>City</th>
            </tr>
        </thhead>
        <tbody>
            ${outputRows}
        </tbody>
    </table>
    `;
};
const pg = require("pg");
const config = require("platformsh-config").config();

exports.usageExample = async function () {
    const credentials = config.credentials("postgresql");

    const client = new pg.Client({
        host: credentials.host,
        port: credentials.port,
        user: credentials.username,
        password: credentials.password,
        database: credentials.path,
    });

    client.connect();

    // Creating a table.
    await client.query(
        `CREATE TABLE IF NOT EXISTS People (
            id SERIAL PRIMARY KEY,
            name VARCHAR(30) NOT NULL,
            city VARCHAR(30) NOT NULL
        )`
    );

    // Insert data.
    await client.query(
        `INSERT INTO People (name, city)
        VALUES
            ('Neil Armstrong', 'Moon'),
            ('Buzz Aldrin', 'Glen Ridge'),
            ('Sally Ride', 'La Jolla');`
    );

    // Show table.
    const result = await client.query("SELECT * FROM People");

    // Drop table.
    await client.query("DROP TABLE People");

    const outputRows = result.rows
        .map(({ name, city }) => `<tr><td>${name}</td><td>${city}</td></tr>\n`)
        .join("\n");

    return `
    <table>
        <thead>
            <tr>
                <th>Name</th><th>City</th>
            </tr>
        </thhead>
        <tbody>
            ${outputRows}
        </tbody>
    </table>
    `;
};
const redis = require('redis');
const config = require("platformsh-config").config();
const { promisify } = require('util');

exports.usageExample = async function() {
    const credentials = config.credentials('redis');
    const client = redis.createClient(credentials.port, credentials.host);

    // The Redis client is not Promise-aware, so make it so.
    const redisGet = promisify(client.get).bind(client);
    const redisSet = promisify(client.set).bind(client);

    const key = 'Deploy day';
    const value = 'Friday';

    // Set a value.
    await redisSet(key, value);

    // Read it back.
    const test = await redisGet(key);

    return `Found value <strong>${test}</strong> for key <strong>${key}</strong>.`;
};
const solr = require("solr-node");
const config = require("platformsh-config").config();

exports.usageExample = async function () {
    const client = new solr(config.formattedCredentials("solr", "solr-node"));

    // Add a document.
    const addResult = await client.update({
        id: 123,
        name: "Valentina Tereshkova",
    });

    // Flush writes so that we can query against them.
    await client.softCommit();

    // Select one document:
    const strQuery = client.query().q();
    const writeResult = await client.search(strQuery);

    // Delete one document.
    const deleteResult = await client.delete({ id: 123 });

    return `
    Adding one document. Status (0 is success): ${addResult.responseHeader.status}<br />
    Selecting documents (1 expected): ${writeResult.response.numFound}<br />
    Deleting one document. Status (0 is success): ${deleteResult.responseHeader.status}<br />
    `;
};

Project templates 

A number of project templates for Node.js applications and typical configurations are available on GitHub. Not all of them are proactively maintained but all can be used as a starting point or reference for building your own website or web application.

Elastic APM with Kibana

Elastic APM with Kibana

This template builds Elastic APM (Application Performance Monitoring) with a Kibana front-end. It is intended as a complete self-contained monitoring solution, although authentication needs to be configured for your specific application.

Features:

  • Elasticsearch 7.2

View the repository on GitHub.

Deploy on Platform.sh

Express

Express

This template demonstrates building the Express framework for Platform.sh. It includes a minimalist application skeleton that demonstrates how to connect to a MariaDB server. It is intended for you to use as a starting point and modify for your own needs.

Express is a minimalist web framework written in Node.js.

Features:

  • Node.js 14
  • MariaDB 10.4
  • Automatic TLS certificates
  • npm-based build

View the repository on GitHub.

Deploy on Platform.sh

Gatsby

Gatsby

This template builds a simple application using Gatsby. Gatsby is a free and open source framework based on React that helps developers build blazing fast websites and apps. The website is statically generated by a Node.js application during the build step, and then served statically at runtime.

Gatsby is a free and open source framework based on React that helps developers build blazing fast websites and apps.

Features:

  • Node.js 14
  • Automatic TLS certificates
  • yarn-based build

View the repository on GitHub.

Deploy on Platform.sh

Gatsby with Drupal

Gatsby with Drupal

This template builds a two-application project to deploy the Headless CMS pattern using Gatsby as its frontend and Drupal for its backend. The gatsby-source-drupal source plugin is used to pull data from Drupal during the post_deploy hook into the Gatsby Data Layer and build the frontend site. Gatsby utilizes the Platform.sh Configuration Reader library for Node.js to define the backend data source in its configuration. It is intended for you to use as a starting point and modify for your own needs.

Note that after you have completed the Drupal installation and included a few articles, the project will require a redeploy to build and deploy Gatsby for the first time. See the included README's post-install section for details.

Gatsby is a free and open source framework based on React that helps developers build statically-generated websites and apps, and Drupal is a flexible and extensible PHP-based CMS framework.

Features:

  • Node.js 12
  • PHP 7.4
  • MariaDB 10.4
  • Redis 5.0
  • Automatic TLS certificates
  • npm-based build for Gatsby
  • Composer-based build for Drupal
  • Multi-app configuration
  • Delayed SSG build (post deploy hook)

View the repository on GitHub.

Deploy on Platform.sh

Gatsby with Strapi

Gatsby with Strapi

This template builds a two application project to deploy the Headless CMS pattern using Gatsby as its frontend and Strapi for its backend. The `gatsby-source-strapi` source plugin is used to pull data from Strapi during the `post_deploy` hook into the Gatsby Data Layer and build the frontend site. Gatsby utilizes the Platform.sh Configuration Reader library for Node.js to define the backend data source in its configuration. It is intended for you to use as a starting point and modify for your own needs.

Note that there are several setup steps required after the first deploy to create your first content types and access permissions in Strapi. See the included README's post-install section for details.

Gatsby is a free and open source framework based on React that helps developers build blazing fast websites and apps, and Strapi is a Headless CMS framework written in Node.js.

Features:

  • Node.js 14
  • PostgreSQL 12
  • Automatic TLS certificates
  • yarn-based build
  • Multi-app configuration
  • Delayed SSG build (post deploy hook)

View the repository on GitHub.

Deploy on Platform.sh

Gatsby with Wordpress

Gatsby with Wordpress

This template builds a two application project to deploy the Headless CMS pattern using Gatsby as its frontend and Wordpress for its backend. The `gatsby-source-wordpress` source plugin is used to pull data from Wordpress during the `post_deploy` hook into the Gatsby Data Layer and build the frontend site. Gatsby utilizes the Platform.sh Configuration Reader library for Node.js to define the backend data source in its configuration. It is intended for you to use as a starting point and modify for your own needs.

Note that after you have completed the Wordpress installation, the project will require a redeploy to build and deploy Gatsby for the first time. See the included README's post-install section for details.

Gatsby is a free and open source framework based on React that helps developers build statically-generated websites and apps, and WordPress is a blogging and lightweight CMS written in PHP.

Features:

  • Node.js 14
  • PHP 7.4
  • MariaDB 10.4
  • Automatic TLS certificates
  • npm-based build for Gatsby
  • Composer-based build for Wordpress
  • Multi-app configuration
  • Delayed SSG build (post deploy hook)

View the repository on GitHub.

Deploy on Platform.sh

Koa

Koa

This template demonstrates building the Koa framework for Platform.sh. It includes a minimalist application skeleton that demonstrates how to connect to a MariaDB server for data storage. It is intended for you to use as a starting point and modify for your own needs.

Koa is a lightweight web microframework for Node.js.

Features:

  • Node.js 10
  • MariaDB 10.2
  • Automatic TLS certificates
  • npm-based build

View the repository on GitHub.

Deploy on Platform.sh

Next.js

Next.js

This template builds a simple application using the Next.js web framework. It includes a minimal application skeleton that demonstrates how to set up an optimized build using Next.js and Yarn, as well as how to begin defining individual pages (such as the /api/hello) endpoint that comes pre-defined with this template.

Next.js is an open-source web framework written for Javascript.

Features:

  • Node.js 14
  • Automatic TLS certificates
  • yarn-based build

View the repository on GitHub.

Deploy on Platform.sh

Node.js

Node.js

This template builds a simple application using the Node.js built-in `http` web server. It includes a minimalist application skeleton that demonstrates how to connect to the included MariaDB server, but you are free to alter it as needed.

Node.js is an open-source JavaScript runtime built on Chrome's V8 JavaScript engine.

Features:

  • Node.js 14
  • MariaDB 10.4
  • Automatic TLS certificates
  • npm-based build

View the repository on GitHub.

Deploy on Platform.sh

NuxtJS

NuxtJS

This template builds a simple application using the NuxtJS web framework that can be used as a starting point.

NuxtJS is an open-source web framework based on Vue.js.

Features:

  • Node.js 14
  • Automatic TLS certificates
  • yarn-based build

View the repository on GitHub.

Deploy on Platform.sh

Probot

Probot

This template builds a simple GitHub App using [Probot](https://github.com/probot/probot) for Node.js. It includes a minimalist skeleton GitHub app that demonstrates a basic GitHub connection response. It is intended for you to use as a starting point and modify for your own needs.

Note that there are several setup steps required after first deploy to connect your project to GitHub. See the included README file for details.

Probot is a framework for building GitHub Apps in Node.js.

Features:

  • Node.js 12
  • Automatic TLS certificates
  • npm-based build

View the repository on GitHub.

Deploy on Platform.sh

strapi

strapi

This template builds a Strapi backend for Platform.sh, which can be used to quickly create an API that can be served by itself or as a Headless CMS data source for another frontend application in the same project. This repository does not include a frontend application, but you can add one of your choice and access Strapi by defining it in a relationship in your frontend's .platform.app.yaml file.

Strapi is a Headless CMS framework written in Node.js.

Features:

  • Node.js 12
  • PostgreSQL 12
  • Automatic TLS certificates
  • npm-based build
  • OpenAPI spec generation
  • Automatic public API documentation

View the repository on GitHub.

Deploy on Platform.sh