reading time 5 mins

This guide will show you to use Doppler to supply app config and secrets to your PM2 managed Node.js applications.

You can also check out a complete working example at


  • You're familiar with PM2
  • The Doppler CLI is installed
  • You're familiar with provising machines for deployment and CI/CD systems

Service Token

Accessing your secrets in production or CI/CD environment requires a Service Token to provide read-only access to a specific config and we'll cover how to provide this in the Deployment section.


The Doppler CLI works with PM2 by injecting secrets using either a bash or node script.


Using a bash script is recommended unless you're in an environment where bash doesn't exist (e.g. Windows without WSL).

Create a script that will call doppler run using the following naming conventions (PM2 only recognizes .sh, .js, and .py files):

  • bash: bin/
  • node: `bin/doppler-run.js'
doppler run -- npm start
import { spawn } from 'child_process'

const doppler = spawn('doppler', ['run', '--', 'npm', 'start'])
doppler.stdout.on('data', (data) => console.log(`${data}`))
doppler.stderr.on('data', (data) => console.error(`${data}`))

Now start your application using PM2:

pm2 start bin/
pm2 start bin/doppler-run.js

To stop or delete your application, use the name of the script without the file extension:

pm2 stop doppler-run
pm2 delete doppler-run


Using Doppler with PM2 in a Docker container simply requires the installation of bash and the Doppler CLI (which is likely already installed if using a non-Alpine-based Node image).

Below is a complete and production-ready example Dockerfile:

FROM node:lts-alpine

# NOTE: PM2 requires bash to be installed
RUN apk add bash

# Install Doppler CLI
RUN (curl -Ls --tlsv1.2 --proto "=https" --retry 3 || wget -t 3 -qO- | sh

WORKDIR /usr/src/app
ENV PATH=$PATH:/usr/src/app/node_modules/.bin

COPY package.json package-lock.json ./
RUN npm clean-install --only=production --silent --no-audit && mv node_modules ../
COPY . .

# The `pm2-runtime` script is required when using Docker
CMD ["pm2-runtime", "bin/"]

Then to start the container, pass in a Doppler Service token as the DOPPLER_TOKEN environment variable:

# Presumes the DOPPLER_TOKEN environment variable is set in the hosting environment
docker run -e DOPPLER_TOKEN="$DOPPLER_TOKEN" your/docker-image


Configuring the Doppler CLI in production requires a Doppler Service Token and there are two ways to supply this to your PM2 application.

Option 1: Preconfiguring the Doppler CLI (preferred)

Pre-configuring the Doppler CLI when provisioning the production machine is the most secure option and works by scoping the Doppler Service Token to the location of the application directory. This only needs to be performed once.

For example, if your app is checked out to /home/ubuntu/your-app then the command would be the following (replacing with your Service Token):

doppler configure set token --scope /home/ubuntu/your-app

# Security measure by removing the Service Token value from bash history
history -c

Option 2: ecosystem.config File

You can use an ecosystem.config file to store the service token but do not commit this to your repository.

Instead, this value should be dynamically inserted by a CI/CD deployment job. For example, this could be the run step in a GitHub Action:

# Uses bash heredoc syntax -
cat << EOF > ecosystem.config.js
module.exports = {
  apps: [{
    script: 'bin/',
    env: {
      DOPPLER_TOKEN: '${{ secrets.DOPPLER_TOKEN }}'


Awesome Work!

Now you know how to use Doppler to supply secrets to your PM2 managed Node.js applications.

Did this page help you?