---
title: "Getting started"
date: "2025-04-08T12:55:36+00:00"
summary: "Learn how to set up, configure, and deploy your Node.js app on Acquia's Front End Hosting platform with step-by-step instructions and framework-specific guidance."
image:
type: "page"
url: "/acquia-cloud-platform/add-ons/node-js/getting-started"
id: "e7570e63-6d80-498e-b29d-5d8f04b505f7"
---

Table of contents will be added

Front End Hosting - Advanced provisions a Node.js application with the following environments:

*   Development (Dev)
    
*   Staging (Stage)
    
*   Production (Prod)
    

Viewing an application
----------------------

1.  Sign in to the Cloud Platform user interface.
2.  In the top menu, click **Develop**.
    
3.  Select your organization.
4.  Select an application.
5.  Click **View <application name>**.
    
    ![nodejs_view-application](https://acquia.widen.net/content/3ac8fe6f-ada8-448b-84b2-71ab14e200d4/web/d7fbc_nodejs_view-application.png?w=720&itok=krhIPdUU)
    
    New environments are provisioned with the default content page.
    
    ![nodejs_application-page](https://acquia.widen.net/content/594cdad6-754e-4ba7-8ad2-46d5d3b8a2ca/web/c9156_nodejs_application-page.jpg)
    
6.  To verify that a site works correctly, visit the default URL of a specific environment.

Setting up
----------

1.  [Add a public key to your Acquia profile](/acquia-cloud-platform/adding-public-key-acquia-profile "Adding a public key to an Acquia profile").
2.  [Clone the application’s repository](/acquia-cloud-platform/checking-out-local-copy-your-code "Checking out a local copy of your code").
3.  [Copy your code to a new Git repository](/acquia-cloud-platform/copying-your-code-new-git-repository "Copying your code to a new Git repository").

Note

To use external CI/CD, visit [Continuous Integration and Continuous Deployment](/acquia-cloud-platform/add-ons/node-js/configuring-external-cicd "Configuring external CI/CD") and skip Steps 4 and 5.

4.  Configure the `package.json` file.
    
    The `package.json` file must be located in the root folder of your project that contains the following commands. These are required to host a NodeJS site.
    
5.  Build command configuration.
    
    Set `npm install && npm run build` as the build command in the NodeJS Hosting build system to ensure a robust and efficient deployment process.
    
        "scripts": {
            ...
            "build": "npm install && next build",
            "start": "next start",
          },
         	 
    

Note

It is not required to define the dependencies in the build command if they are already installed in the Git branch.

Framework-based custom configuration
------------------------------------

​Configure the start script in your package.json file in order to initiate the production server. Use the command that corresponds to your specific framework.

### Node.js

    {
      "scripts": {
        "build": "npm install",
        "start": "node index.js"
      },
    }

### Next.js

    {
      "scripts": {
        "build": "npm install && next build",
        "start": "next start"
      }
    }

### **Nuxt**

    {
      "scripts": {
        "build": "npm install && nuxt build",
        "start": "nuxt start"
      }
    }

### React

    {
      "scripts": {
        "build": "npm install && react-scripts build",
        "start": "react-scripts start",
      }
    }

### Angular

    {
      "scripts": {
        "build": "npm install && ng build --prod",
        "start": "ng serve --port $PORT --host 0.0.0.0 --disable-host-check --open",
        "serve": "http-server -c-1 dist/your-project-name"
      }
    }

For Angular.js, when you test this configuration locally, ensure execution of the required commands on a Linux machine.  
Next, run the command `PORT=3000 npm start` to launch the Angular application on any Linux machine.

### Vue

    {
      "scripts": {
        "build": "npm install && vue-cli-service build",
        "start": "serve -s dist",
        "serve": "vue-cli-service serve",
      }
    }

To serve production builds of frameworks like Angular, React, and Vue, Acquia recommends you to use either serve or http-server. These Node.js packages provide simple and efficient ways to host static files.

### Installation

Install your preferred package using npm:

    $ npm install serve

or

    $ npm install http-server

### Usage

After you build the project (typically into a dist directory), start the production server with the following commands:

    serve -s dist

    http-server dist

For easy deployment, you can also include these commands in the start script of your `package.json`.

Note

Ensure that your build output is located in the `dist` directory (or adjust the path in the commands accordingly).

Implementing autoscaling
------------------------

Autoscaling is vital to enhance the performance of your application and enable it to handle variable workloads. This feature dynamically adjusts the number of active instances of your environment based on its real-time performance metrics. The enablement process revolves around integrating the `acquia-autoscaling` javascript into your project that collects the necessary metrics.

To implement autoscaling in your application:

1.  Add the `acquia-autoscaling.js` script to the root directory of your project.
    
    The following code snippets show the content of the scripts:
    
    ### ES5/CommonJS syntax
    
        // ES5/CommonJS syntax
        // acquia-autoscaling.js
        const { collectDefaultMetrics, Registry } = require("prom-client");
        const http = require("http");
        const net = require("net");
        function startMetricsSvr() {
            // Create a new registry to track default metrics
            const register = new Registry();
           // Enable the collection of default metrics
            collectDefaultMetrics({ register });
           // Set up an HTTP server to expose the metrics
           const server = http.createServer(async (req, res) => {
                if (req.url === "/metrics") {
                    try {
                        // Respond with metrics in Prometheus format
                        res.setHeader("Content-Type", register.contentType);
                        const metrics = await register.metrics();
                        res.end(metrics);
                    } catch (err) {
                        res.writeHead(500);
                        res.end(err.message);
                    }
                } else {
                    res.writeHead(404);
                    res.end("Not Found");
                }
            });
           const monitoringPort = 9100;
            server.listen(monitoringPort, () => {
                console.log(
                    `Acquia Node.js Monitoring server listening on port ${monitoringPort}`
                );
            });
            // Prevent the Node.js process from exiting
            process.stdin.resume();
        }
        const originalListen = net.Server.prototype.listen;
        let injected = false;
        net.Server.prototype.listen = function (...args) {
            try {
                const port =
                    typeof args[0] === "number"
                        ? args[0]
                        : typeof args[0] === "string" && !isNaN(parseInt(args[0]))
                        ? parseInt(args[0])
                        : args[0] && typeof args[0].port === "number"
                        ? args[0].port
                        : args[0] &&
                          typeof args[0].port === "string" &&
                          !isNaN(parseInt(args[0].port))
                        ? parseInt(args[0].port)
                        : null;
                if (port === 3000 && !injected) {
                    injected = true;
                    setTimeout(startMetricsSvr, 1000);
                }
            } catch (err) {
                console.error(err);
            }
           return originalListen.apply(this, args);
        };
    
    ### ES6/ES Modules syntax
    
        // ES6/ES Modules syntax
        // acquia-autoscaling.js
        import { collectDefaultMetrics, Registry } from "prom-client";
        import http from "http";
        import net from "net";
        function startMetricsSvr() {
            // Create a new registry to track default metrics
            const register = new Registry();
           // Enable the collection of default metrics
            collectDefaultMetrics({ register });
           // Set up an HTTP server to expose the metrics
           const server = http.createServer(async (req, res) => {
                if (req.url === "/metrics") {
                    try {
                        // Respond with metrics in Prometheus format
                        res.setHeader("Content-Type", register.contentType);
                        const metrics = await register.metrics();
                        res.end(metrics);
                    } catch (err) {
                        res.writeHead(500);
                        res.end(err.message);
                    }
                } else {
                    res.writeHead(404);
                    res.end("Not Found");
                }
            });
           const monitoringPort = 9100;
            server.listen(monitoringPort, () => {
                console.log(
                    `Acquia Node.js Monitoring server listening on port ${monitoringPort}`
                );
            });
            // Prevent the Node.js process from exiting
            process.stdin.resume();
        }
        const originalListen = net.Server.prototype.listen;
        let injected = false;
        net.Server.prototype.listen = function (...args) {
            try {
                const port =
                    typeof args[0] === "number"
                        ? args[0]
                        : typeof args[0] === "string" && !isNaN(parseInt(args[0]))
                        ? parseInt(args[0])
                        : args[0] && typeof args[0].port === "number"
                        ? args[0].port
                        : args[0] &&
                          typeof args[0].port === "string" &&
                          !isNaN(parseInt(args[0].port))
                        ? parseInt(args[0].port)
                        : null;
                if (port === 3000 && !injected) {
                    injected = true;
                    setTimeout(startMetricsSvr, 1000);
                }
            } catch (err) {
                console.error(err);
            }
           return originalListen.apply(this, args);
        };
    
2.  Edit the `package.json` file to add the `NODE_OPTIONS='-r ./acquia-autoscaling.js'` string before the original `start` command of your application:
    
    ### Node.js
    
        {
         "scripts": {
           "start": "NODE_OPTIONS='-r ./acquia-autoscaling.js' node app.js",
           "build": "npm install"
         },
        }
    
    ### Next.js
    
        {
         "scripts": {
           "start": "NODE_OPTIONS='-r ./acquia-autoscaling.js' next start",
           "build": "npm install && next build"
         }
        }
    
    ### Nuxt
    
        {
         "scripts": {
           "start": "NODE_OPTIONS='--import ./acquia-autoscaling.js' node .output/server/index.mjs",
           "build": "npm install && nuxt build"
         }
        }
    
    ### React
    
        {
         "scripts": {
           "start": "NODE_OPTIONS='-r ./acquia-autoscaling.js' serve -s build",
           "build": "npm install && react-scripts build"
         }
        }
    
    ### Angular
    
        {
         "scripts": {
           "start": "NODE_OPTIONS='-r ./acquia-autoscaling.js' serve -s dist/sample-angular/browser/",
           "build": "npm install && ng build --configuration production"
         }
        }
    
    ### Vue
    
        {
         "scripts": {
           "start": "NODE_OPTIONS='-r ./acquia-autoscaling.js' serve -s dist",
           "build": "npm install && vue-cli-service build"
         }
        }
    
    Important
    
    Ensure that you place the string right before the main entry point of your application in the `start` script. Otherwise, the autoscaling feature might become inoperative.
    
3.  Run the following NPM command in your Node.js code repository on your local machine to install the `prom-client` dependency:
    
        npm install prom-client
    
    This command adds the `prom-client` package to the dependencies of your application.
    
    Important
    
    *   Install the `prom-client` package correctly, as it is mandatory for the `acquia-autoscaling.js` script to work.
    *   After you execute the `prom-client` install command, ensure that `prom-client` is added as a dependency in your `package.json` file. The `package.json` file must contain an entry for `prom-client` under dependencies to confirm successful installation.
    
    Verify the functionality of your application to ensure that metrics are being correctly exposed and autoscaling is operational.
    
    After successful implementation and verification, your application can scale automatically to adapt to usage patterns and sustain optimal performance.
    

Environment variables configuration
-----------------------------------

For information about how to configure environment variables, visit [Creating custom environment variables](https://docs.acquia.com/acquia-cloud-platform/docs/manage-apps/variables).

To use the latest environment variable values in your Node.js code, incorporate them during the Node.js build process. Build-time environment variables are injected during the build and remain fixed until redeployment. Runtime environment variables are read by the application at execution and update without redeployment.

Note

Refer to the framework documentation of your application to understand how runtime and build-time environment variables are managed.

Deployment workflow
-------------------

When you trigger deployment, build is triggered implicitly.

1.  Visit [Deployment workflow](/acquia-cloud-platform/add-ons/node-js/deployment-workflow "Deployment workflow").
2.  Set the post deployment cloud actions to clear Varnish cache after you deploy the branch through the Cloud Platform user interface.
    
    ![nodejs_deployment-workflow-edit-button](https://acquia.widen.net/content/c146b843-ceb6-4c08-8d30-21408c456565/web/c25a3_nodejs_deployment-workflow-edit-button.png?w=1090&itok=fdUH3Ze7)
    
    ![nodejs_deployment-workflow-clear-varnish-cache](https://acquia.widen.net/content/a6f18438-202b-4d68-ae72-4609af5c993f/web/2e745_nodejs_deployment-workflow-clear-varnish-cache.png?w=1090&itok=Vj2E8kcm)
    
    After the code deployment task for the deployed branch completes, the latest code changes are visible in the environment.
    

Note

Follow-up commits to the deployed branch trigger automatic deployment.

Subscription details
--------------------

For information about how to access your subscription details, visit [Viewing subscriptions](https://docs.acquia.com/acquia-cloud-platform/managing-subscriptions#section-viewing-subscriptions).

Monitoring
----------

To monitor instructions, visit [Using Stack Metrics to monitor activity on your environments](https://docs.acquia.com/acquia-cloud-platform/docs/monitoring-infrastructure/stackmetrics).

Build minutes
-------------

As part of the code build/deployment process, multiple commands run in the backend to produce a build artifact and deploy it to an environment. These include:

*   `git` commands to clone code from an application repository.
*   `npm run-build` commands to produce the deployable bundle of an environment branch.
*   The time taken to deploy the build to the specific environment.

### Application deployment

The total build time is tracked as build minutes.

*   If a customer exceeds their allocated build minutes, they may continue to use Front End Hosting - Advanced without interruption. An Account Manager is notified, and the account holder is contacted to discuss upgrading their assigned entitlement for build minutes.
*   Build is implicitly triggered with each deployment. Build logs are visible in “Task Logs” in Cloud UI. A build is retriggered 2 times upon failure.
*   Post Deployment Cloud Actions can be enabled/disabled to clear Varnish/CDN cache.

### Domain configuration

*   Visit [Managing domains](http://docs.acquia.com/acquia-cloud-platform/docs/manage-apps/domains)

### CDN configuration

*   Visit [Cloud Platform CDN](https://docs.acquia.com/acquia-cloud-platform/docs/features/platformcdn)

Readiness probe path and authentication considerations
------------------------------------------------------

In Frontend Hosting – Advanced environments, the Kubernetes readiness probe uses the root path (`/`) to check application health. This probe periodically sends HTTP requests to the `/` endpoint to verify readiness.

Note

Do not apply any authentication, such as Basic Auth, OAuth, JWT, or SSO, to the `/` endpoint. When you force authentication on this path, the Kubernetes readiness probe is prevented from working, which can result in `503 Service Unavailable` errors and may cause the application to be marked as unhealthy.

If your site requires authentication, configure your authentication middleware to bypass checks for requests from `kube-probe/1.31+` and `curl` on the `/` endpoint. Review the following information about these checks:

*   Requests from `curl` to the application `/` endpoint are part of the pre-deployment check. If this check fails, the deployment is marked as failed.
*   Requests from `kube-probe/1.31+` to the application `/` endpoint are part of the post-deployment check. If this check fails, Kubernetes readiness checks fail and the request traffic is not forwarded to the application.
    

Follow this guidance to ensure reliable health checks and stable application operation within the Acquia environment.