This page explains your options to install the Node.js Agent in a containerized environment:

Use Auto-Instrumentation

This scenario applies to containers running in Kubernetes where the Cluster Agent is installed.

This option uses the Auto-Instrumentation feature of the Cluster Agent. It is the recommended option because it offers the highest level of automation and the simplest operational experience for instrumenting Node.js applications in a Kubernetes cluster.

To get started, see Auto-Instrument Applications with the Cluster Agent.

Use Init Containers

This option applies to containers running in Kubernetes.

This option uses Kubernetes init containers to copy the Node.js Agent binaries into the application container when the application starts up. It assumes that the application image is built without any Node.js Agent binaries and that a second init container image is built which contains the Node.js Agent binaries. The deployment spec for the application is configured to copy and send the agent binaries to the running application container.

To copy the agent binaries with init containers:

  1. Build the Node.js Application Image
  2. Build the Node.js Agent Init Container Image
  3. Add the Init Container to the Deployment Spec
  4. Set the Node.js Agent Environment Variables
  5. Set the UNIQUE_HOST_ID Environment Variable
  6. (On-Premises Controller Only) Copy the Controller Certs to the Container

These steps assume the application image is built using Node.js version 8 and later, which supports the NODE_OPTIONS environment variable. This environment variable is set in a ConfigMap. For Node.js versions 7 and earlier, refer to this example that uses a start script to include the appdynamics package.

Build the Node.js Application Image

Build the Node.js application image based on the application binaries and dependencies. Do not include the Node.js Agent binaries or settings in the application image.

Build the Node.js Agent Init Container Image

The agent init container image is built separately from the application image and can be reused across multiple Node.js application deployments. 

For Linux and Alpine environments, the Node.js Agent init container images are available on Dockerhub. For all other deployment environments, continue with the following instructions to build the init container image.

The Node.js and operating system versions of the init container image should match the Node.js and operating system versions of the application image to ensure that compatible Node.js Agent binaries are selected when running npm install. For more information, see Node.js Supported Environments.

The Node.js and operating system versions are determined by the FROM node:14.4-alpine statement in the Dockerfile:

FROM node:14.4-alpine
…
JS


Follow these steps to build the init container image:

  1. Create a shim.js file that contains a require statement for appdynamics. Set the reuseNode property to true. Set reuseNodePrefix to the value of an environment variable that will be provided in a ConfigMap in a later step:

    require("appdynamics").profile({
      reuseNode: true,
      reuseNodePrefix: process.env.APPDYNAMICS_AGENT_REUSE_NODE_NAME_PREFIX
    });
    JS
  2. If the Node.js Agent should report Transaction Analytics data, add the analytics properties to the require statement and set the value to environment variables that will be provided in a ConfigMap in a later step. See Node.js Settings Reference.

    require("appdynamics").profile({
      reuseNode: true,
      reuseNodePrefix: process.env.APPDYNAMICS_AGENT_REUSE_NODE_NAME_PREFIX,
      analytics: {
        host: process.env.APPDYNAMICS_ANALYTICS_HOST_NAME,
        port: process.env.APPDYNAMICS_ANALYTICS_PORT,
        ssl: process.env.APPDYNAMICS_ANALYTICS_SSL_ENABLED  
      }
    });
    JS
  3. If the Node.js Agent communicates with an on-premises Controller, add the certificateFile property and set it to the location where the cert file will be copied in a later step:

    require("appdynamics").profile({
      reuseNode: true,
      reuseNodePrefix: process.env.APPDYNAMICS_AGENT_REUSE_NODE_NAME_PREFIX,
      certificateFile: /opt/appdynamics/cacerts
    });
    JS
  4. In the Dockerfile, copy shim.js to the image:

    COPY ./shim.js /opt/appdynamics/shim.js
    JS
  5. Run the npm install command to resolve the appdynamics package:

    $ cd appdynamics
    $ npm install appdynamics@next
    JS
  6. In the Dockerfile, copy the contents of the folder containing the appdynamics package to the image:

    COPY appdynamics/ /opt/appdynamics/
    JS

For a complete example of building the Node.js Agent init container image using a multi-stage build, see this Dockerfile.

Add the Init Container to the Deployment Spec

Edit the deployment spec to add the sections required to copy the agent binaries from the init container to the application image.

The following snippet from a deployment spec shows the required volumesvolumeMounts, and initContainer definitions. It assumes the Node.js application image is published to myrepo/nodejs-app:v1 and the init container image is published to myrepo/appd-nodejs:latest. The shim.js file from the init container image is copied to /opt/appdynamics/shim.js in the application container.

kind: Deployment
spec:
  containers:
  - name: nodejs-app
	image: myrepo/nodejs-app:v1
    volumeMounts:
    - mountPath: /opt/appdynamics
      name: appd-agent-repo
  initContainers:
  - command:
    - cp
    - -r
    - /opt/appdynamics/.
    - /opt/temp
	name: appd-agent
    image: myrepo/appd-nodejs:latest
    volumeMounts:
    - mountPath: /opt/temp
      name: appd-agent-repo
  volumes:
    - name: appd-agent-repo
      emptyDir: {}
YML

Set the Node.js Agent Environment Variables

To set all of the required Node.js Agent environment variables, try the following options depending on your use case: 

See Best Practices to Configure Agents in Kubernetes for more information.

Use ConfigMaps to Configure the App Server Agent

  1. Use a ConfigMap to set the agent environment variables that are shared across Node.js applications in a namespace. For example, see this appd-nodejs-config.yaml snippet:

    apiVersion: v1
    data:
      APPDYNAMICS_AGENT_APPLICATION_NAME: eCommerce
      APPDYNAMICS_AGENT_ACCOUNT_NAME: <value>
      APPDYNAMICS_CONTROLLER_HOST_NAME: <value>
      APPDYNAMICS_CONTROLLER_PORT: <value>
      APPDYNAMICS_CONTROLLER_SSL_ENABLED: <value>
      APPDYNAMICS_AGENT_REUSE_NODE_NAME_PREFIX: <value>
      APPDYNAMICS_AGENT_NODE_NAME: <value> # not used in node name but required by Node.js agent
      APPDYNAMICS_LOGGER_OUTPUT_TYPE: console
      NODE_OPTIONS: '--require /opt/appdynamics/shim.js'
      # variables required to send transaction analytics data
      APPDYNAMICS_ANALYTICS_HOST_NAME: <value>
      APPDYNAMICS_ANALYTICS_PORT: <value>
      APPDYNAMICS_ANALYTICS_SSL_ENABLED: <value>
    kind: ConfigMap
    metadata:
      name: appd-nodejs-config 
    YML

    The NODE_OPTIONS environment variable, supported in Node.js 8 and later, sets the --require option to the location of the shim.js file copied from the init container image. The analytics host, port and ssl settings depend on how the Analytics Agent is deployed. See Deploy Analytics in Kubernetes for options.

  2. Apply the ConfigMap to the namespace:

    $ kubectl -n ecommerce apply -f appd-nodejs-config.yaml 
    BASH
  3. Update the deployment spec to reference the ConfigMap:

    spec:
      containers:
      - name: nodejs-app
        envFrom:
        - configMapRef:
            name: appd-nodejs-config
     ...
    YML

Use Secrets for the Controller Access Key

  1. Create a Secret using kubectl:

    $ kubectl -n ecommerce create secret generic appd-agent-secret --from-literal=access-key=<access-key>
    BASH
  2. Update the deployment spec to reference the Secret:

    spec:
      containers:
      - name: nodejs-app
        env:
        - name: APPDYNAMICS_AGENT_ACCOUNT_ACCESS_KEY
          valueFrom:
            secretKeyRef:
              name: appd-agent-secret
              key: access-key
     ...
    YML

Set Application-Specific Configuration in the Deployment Spec

Set the application-specific tier name environment variable APPDYNAMICS_AGENT_TIER_NAME in the deployment spec:

spec:
  containers:
  - name: nodejs-app
    env:
    - name: APPDYNAMICS_AGENT_TIER_NAME
      value: nodejs-service
YML

Set the UNIQUE_HOST_ID Environment Variable

Set the UNIQUE_HOST_ID environment variable to enable APM correlation with the Cluster Agent. Since the value depends on a runtime value, set this environment variable in the container startup command with the values in Manually Configure App Agents to Correlate with the Cluster Agent

For a Kubernetes environment with the Docker runtime, set the environment variable as shown in the following example:

spec:
  containers:
    command: ["/bin/sh"]
    args: ["-c", "export UNIQUE_HOST_ID=$(sed -rn '1s#.*/##; 1s/(.{12}).*/\\1/p' /proc/self/cgroup) && node /nodejsapp/myapp.js"]
YML

(On-Premises Controller Only) Copy the Controller Certs to the Container

If on-premises Controller certs are required, define a ConfigMap to reference the cert file and use a volume mount in the deployment spec to mount the ConfigMap contents to the container. See Controller SSL and Certificates.

$ kubectl create configmap appd-cert --from-file=cacerts
BASH

Add the cert file to the container file system using volumes and volumeMounts as shown in the deployment spec snippet:

kind: Deployment
spec:
  containers:
    image: myrepo/nodejs-app:v1
    volumeMounts:
    - name: appd-cert
      subPath: cacerts
      mountPath: /opt/appdynamics/cacerts
  volumes:
    - name: appd-cert
      configMap:
        name: appd-cert
YML

The mountPath value should match the certificateFile property in the shim.js file used when building the init container image.

Example Configuration for Using an Init Container

See this deployment spec for a complete example using an init container to copy the agent binaries.

Use a Dockerfile

This option applies to containers running in Docker and Kubernetes.

This option uses a Dockerfile to include the Node.js Agent binaries in the Docker image at build time. It assumes a single image is built that contains the application and Node.js Agent binaries.

To include the agent in the application image during the image build:

  1. Perform the Node.js Agent Installation Steps
  2. Copy the Application Folder to the Image
  3. Set the Node.js Agent Environment Variables 
  4. Set the UNIQUE_HOST_ID Environment Variable
  5. (On-Premises Controller only) Copy the Controller Certs to the Image

Perform the Node.js Agent Installation Steps

Perform the installation steps described in Install the Node.js Agent.

  1. Run the NPM command to include the appdynamics package from your application folder:

    $ cd nodejsapp
    $ npm install appdynamics@next
    JS
  2. Add the require statement to the application source code and include reuseNode and reuseNodePrefix properties. Set the reuseNodePrefix property to refer to an environment variable that will be set in a later step:

    require("appdynamics").profile({
      reuseNode: true,
      reuseNodePrefix: process.env.APPDYNAMICS_AGENT_REUSE_NODE_NAME_PREFIX
    });
    JS

    The reuse node name and prefix properties are required to support unique naming for multiple container instances for the same application image. See Node.js Settings Reference.

  3. If the Node.js Agent should report transaction analytics data, add the analytics properties to the require statement and set the value to an environment variable that will be set in a later step. See Node.js Settings Reference.

    require("appdynamics").profile({
      reuseNode: true,
      reuseNodePrefix: process.env.APPDYNAMICS_AGENT_REUSE_NODE_NAME_PREFIX,
      analytics: {
        host: process.env.APPDYNAMICS_ANALYTICS_HOST_NAME,
        port: process.env.APPDYNAMICS_ANALYTICS_PORT,
        ssl: process.env.APPDYNAMICS_ANALYTICS_SSL_ENABLED  
      }
    });
    JS

Copy the Application Folder to the Image

Edit the Docker file to copy the application folder to the image:

COPY nodejsapp/ /nodejsapp/
JS

Set the Node.js Agent Environment Variables

If you are running the application in a non-Kubernetes environment (using docker run for example), set the agent environment variables in the Dockerfile. For example:

ENV APPDYNAMICS_AGENT_APPLICATION_NAME=<value>
ENV APPDYNAMICS_AGENT_TIER_NAME=<value>
ENV APPDYNAMICS_AGENT_ACCOUNT_NAME=<value>
ENV APPDYNAMICS_AGENT_ACCOUNT_ACCESS_KEY=<value>
ENV APPDYNAMICS_CONTROLLER_HOST_NAME=<value>
ENV APPDYNAMICS_CONTROLLER_PORT=<value>
ENV APPDYNAMICS_CONTROLLER_SSL_ENABLED=<value>
ENV APPDYNAMICS_AGENT_REUSE_NODE_NAME_PREFIX=<value>
ENV APPDYNAMICS_AGENT_NODE_NAME=<value> # not used in node name but required by Node.js agent
ENV APPDYNAMICS_LOGGER_OUTPUT_TYPE=console
# variables required to send transaction analytics data
ENV APPDYNAMICS_ANALYTICS_HOST_NAME=<value>
ENV APPDYNAMICS_ANALYTICS_PORT=<value>
ENV APPDYNAMICS_ANALYTICS_SSL_ENABLED=<value>
YML

For Kubernetes applications, omit these environment variables from the Dockerfile and set them using ConfigMaps, Secrets, and the deployment spec as described in Use Init Containers. The analytics host, port and ssl settings depend on how the Analytics Agent is deployed. See Deploy Analytics in Kubernetes for options.

Set the UNIQUE_HOST_ID Environment Variable

Set the UNIQUE_HOST_ID environment variable to enable APM correlation with the Cluster Agent. Since the value depends on a runtime value, set this environment variable in the image startup script using the values documented in Manually Configure App Agents to Correlate with the Cluster Agent
For a Kubernetes environment with a Docker runtime, add the following startup script startup.sh to the Docker image in the following example:

#!/bin/bash
# OpenShift 3.10 or 3.11:
UNIQUE_HOST_ID=$(sed -rn '1s#.*/##; 1s/(.{12}).*/\\1/p' /proc/self/cgroup)
exec node /nodejsapp/myapp.js
BASH

(On-Premises Controller only) Copy the Controller Certs to the Image

For Node.js Agents communicating with an on-premises Controller, edit the Dockerfile to copy the cert file containing the on-premises certs to the image. 

For example:

COPY ./onprem-cacerts /opt/appdynamics/cacerts
BASH

Update the application source code to add the certificateFile property in the require statement. Set the certificateFile path to the location of the cert file.

require("appdynamics").profile({
  reuseNode: true,
  reuseNodePrefix: process.env.APPDYNAMICS_AGENT_REUSE_NODE_NAME_PREFIX,
  certificateFile: /opt/appdynamics/cacerts
});
BASH