Skip to main content

Install the Node.js agent using a container

Installing the Node.js agent in a container is essentially the same as the standard installation procedure, except that the installation occurs in a container and, to follow best practices, you should use environment variables to configure the Contrast credentials.

Using environment variables is the most secure method for installing the Node.js agent in a container. Since containers often migrate through QA and production systems, it's a best practice to avoid hard-coding credentials in the container definition.

Before you begin

This topic provides general guidance for installing the Node.js agent in a containerized application, with Docker as an example.

You should have a basic understanding of how containers and related software work. You may need to adjust the instructions to meet your specific circumstances.

Install the agent

Install the Node.js agent using one of these options:

  • Add the agent to the application during development. (recommended)

    This way, the agent will be included with your application’s package.json.

    Use this command to populate the agent into your pipelines and container images.

    npm install @contrast/agent
  • Add the agent to the Dockerfile.

    Add the agent at container build time if you prefer to maintain separate images for the application (with and without the Contrast agent).

    Use this command to add the agent to your existing Dockerfile or into a new Dockerfile that uses your application's image as a base image.

    npm install @contrast/agent

Configure the agent

Follow these instructions when configuring the Node.js agent for an application deployed into a container like Docker (otherwise, see more general information on configuring the Node.js agent). Configuration for the Node.js agent follows this order of precedence.

  • Use environment variables to set application-specific configuration. These can be ENV statements in the Dockerfile or they can be passed to the Docker run command with the -e option. See a list of environment variables commonly used to set application-specific values. You can also refer to the Contrast agent configuration editor to view a full list of variables.

    For example, you could use this command to build your container:

    docker build -t my-app-image

    And then, use these commands when you run the container:

    docker run -p 3000:3000 --name my-app-instance \
    -e "CONTRAST__API__URL=your-ts-url" \
    -e "CONTRAST__API__API_KEY=your-api-key" \
    -e "CONTRAST__API__SERVICE_KEY=your-service-key" \
    -e "CONTRAST__API__USER_NAME=your-user-name" \
    my-app-image

    The process to set environment variables when using a cloud provider typically involves using a secrets manager and then linking the values of those secrets to the environment variable.

Run and verify

  1. If you want to use the Node.js agent rewriter CLI (currently available in the version 4.X and later of the agent), add a RUN instruction and provide the command to invoke the contrast-transpile executable. Then provide your application's entry point.

    RUN npx -p @contrast/agent --no contrast-transpile index.js

    It is important to use the -p @contrast/agent --no options to ensure the npx command is the one from Contrast Security and not from a nefarious person attempting a supply chain attack.

    -p is the shorthand for --package, which tells npx to only use the command in the @contrast/agent package.

    --no is the new option name for the deprecated --no-install option that tells npx to not attempt an install from npm if the command binary is not found.

    The expectation is that the Contrast agent has already been correctly installed along with the npx binaries before attempting to run the npx command.

  2. You must preload the Contrast agent when you launch your application. Normally, you do this in the Dockerfile’s CMD statement, but you can also use an npm script defined in the package.json.

    For example, if you normally start your application with:

    CMD [“node”, “app”]

    Then you can use this command to run the application with Contrast:

    CMD [“node”, “--import”, “@contrast/agent”, “app”]
  3. When the agent starts, it will try to connect to Contrast with authentication keys in the YAML configuration file.

    Tip

    To protect the agent credentials, use the Docker secret and pass them as environment variables during deployment time. For example:

    docker run -e CONTRAST__API_ -e CONTRAST__API__API_KEY=<value> -e CONTRAST__API__SERVICE_KEY=<value> -e CONTRAST__API__USER_NAME=<value> -e CONTRAST__SERVER__ENVIRONMENT=<value> image_with_contrast
  4. Verify that Contrast is running by checking the activity in the container log.

    For example, log activity might look like this:

    @contrast/agent 2.16.8--------------------------------------
    2020-07-20T19:05:14.407Z INFO contrast-service: BUILD {"progname": "Contrast Service", "version": "2.8.1", "buildTime": ""}
    2020-07-20T19:05:14.407Z INFO Building timer for orphan request cleanup {"progname": "Contrast Service", "cleanupMs": 5000}
    2020-07-20T19:05:14.408Z INFO Building timer for orphan app cleanup {"progname": "Contrast Service", "time": 5000}
    2020-07-20T19:05:14.450Z INFO Creating New Application Server {"progname": "Contrast Service", "uuid": "96299b72-f867-4354-b9c9-1eb23511cb8a", "serverName": "bc1bd6e5cd3a", "clientId": "1", "pid": 1}
    2020-07-20T19:05:14.450Z WARN Failed to initialize secure client, falling back to insecure client {"progname": "Contrast Service"}
    2020-07-20T19:05:15.473Z INFO setting new server features for context{"progname": "Contrast Service", "uuid": "96299b72-f867-4354-b9c9-1eb23511cb8a", "serverName": "bc1bd6e5cd3a"}
    2020-07-20T19:05:15.474Z ERROR Error setting up CEF syslog {"progname": "Contrast Service", "err": "open /juice-shop/security.log: permission denied"}
    2020-07-20T19:05:15.475Z INFO starting event scanner {"progname": "Contrast Service", "report": {}}
    2020-07-20T19:05:15.486Z INFO Creating new application {"progname": "Contrast Service", "uuid": "96299b72-f867-4354-b9c9-1eb23511cb8a", "serverName": "bc1bd6e5cd3a", "appName": "juiceshop-guide", "language": "Node", "clientId": "1", "pid": 1}
    2020-07-20T19:05:15.486Z INFO AppCreate: creating and initializing new application {"progname": "Contrast Service", "uuid": "96299b72-f867-4354-b9c9-1eb23511cb8a", "server_name": "bc1bd6e5cd3a", "app_name": "juiceshop-guide", "app_lang": "Node", "client_id": "1", "pid": 1}
    2020-07-20T19:05:15.921Z INFO setting new application settings {"progname": "Contrast Service", "uuid": "96299b72-f867-4354-b9c9-1eb23511cb8a", "serverName": "bc1bd6e5cd3a", "appName": "juiceshop-guide", "language": "Node"}
    2020-07-20T19:05:15.922Z INFO Setting session id on app context: {"progname": "Contrast Service", "uuid": "96299b72-f867-4354-b9c9-1eb23511cb8a", "clientid": "1", "appname": "juiceshop-guide", "applang": "Node", "apppath": "/juice-shop/package.json", "sessionid": "cd0b271e66974162bf5fcca8b32e37b1"}
    Entering main at /juice-shop/appinfo: All dependencies in ./package.json are satisfied (OK)...

See also

Contrast Support Portal Node.js agent with Kubernetes

Contrast Support Portal AWS Fargate and Contrast agents