Sign inSign up

keymetrics/pm2

By keymetrics

•Updated 7 days ago

Production ready Node.js Docker image including the PM2 runtime

Image
145

5M+

keymetrics/pm2 repository overview

⁠PM2

Production ready nodeJS Docker image including the PM2 runtime⁠.

The goal of this image is to wrap your applications into a proper Node.js production environment. It solves major issues when running Node.js applications inside a container like:

  • Correct PID 1 signals Handling & Forwarding
  • Graceful application Start and Shutdown
  • Seamless application clustering to increase performance and reliability

Further than that, using PM2 as a layer between the container and the application brings PM2 features like application declaration file⁠, customizable log system⁠, source map support⁠ and other great features to manage your Node.js application in production environment.

⁠Tags available

Standard images are built from the Dockerfile⁠ on top of the official Node.js images⁠. All images are published for linux/amd64 and linux/arm64. latest points to the newest Node.js release, and keymetrics/pm2:latest is an alias of latest-alpine.

Image NameOperating systemBase image
keymetrics/pm2:latest-alpineAlpine⁠node:alpine
keymetrics/pm2:26-alpineAlpine⁠node:26-alpine
keymetrics/pm2:24-alpineAlpine⁠node:24-alpine
keymetrics/pm2:22-alpineAlpine⁠node:22-alpine
Image NameOperating systemBase image
keymetrics/pm2:latest-bookwormDebian Bookworm⁠node:bookworm
keymetrics/pm2:26-bookwormDebian Bookworm⁠node:26-bookworm
keymetrics/pm2:24-bookwormDebian Bookworm⁠node:24-bookworm
keymetrics/pm2:22-bookwormDebian Bookworm⁠node:22-bookworm
Image NameOperating systemBase image
keymetrics/pm2:latest-trixieDebian Trixie⁠node:trixie
keymetrics/pm2:26-trixieDebian Trixie⁠node:26-trixie
keymetrics/pm2:24-trixieDebian Trixie⁠node:24-trixie
keymetrics/pm2:22-trixieDebian Trixie⁠node:22-trixie
Image NameOperating systemBase image
keymetrics/pm2:latest-slimDebian (minimal packages, follows the node:<version>-slim default)node:slim
keymetrics/pm2:26-slimDebian (minimal packages, follows the node:<version>-slim default)node:26-slim
keymetrics/pm2:24-slimDebian (minimal packages, follows the node:<version>-slim default)node:24-slim
keymetrics/pm2:22-slimDebian (minimal packages, follows the node:<version>-slim default)node:22-slim
⁠Hardened
Image NameBase image
keymetrics/pm2:26-hardeneddhi.io/node:26-debian13
keymetrics/pm2:24-hardeneddhi.io/node:24-debian13
keymetrics/pm2:22-hardeneddhi.io/node:22-debian13

Built from Dockerfile.hardened⁠ on top of Docker Hardened Images⁠: minimal Debian 13, near-zero CVEs, non-root node user (uid 1000), working directory /app. There is no shell, no npm and no package manager at runtime, so install your dependencies in a build stage:

FROM dhi.io/node:24-debian13-dev AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev

FROM keymetrics/pm2:24-hardened
COPY --from=deps /app/node_modules node_modules/
COPY src src/
COPY pm2.json .
CMD ["pm2-runtime", "start", "pm2.json"]

Without ps in the image, PM2 can only stop the main process of an app: child processes spawned by your app are not killed on stop or restart.

⁠Bun
Image NameBase image
keymetrics/pm2:bunoven/bun:1 (Debian)
keymetrics/pm2:bun-alpineoven/bun:1-alpine

Built from Dockerfile.bun⁠: PM2 and your applications run on Bun⁠ instead of Node.js (node is a shim to bun in these images). Install your dependencies with bun install.

The list of built versions lives in versions.json⁠.

You can find more information about the image variants here⁠.

Images are rebuilt every week to pick up Node.js and PM2 releases, and on every push to the master branch of docker-pm2⁠.

Tags for end-of-life Node.js versions (18, 20 and older) and Debian releases (buster, bullseye and older) are no longer rebuilt. They remain on Docker Hub⁠ but do not receive security updates. (Not recommended)

⁠Usage

Let's assume the following folder structure for your project.

`-- your-app-name/
    |-- src/
        `-- app.js
    |-- package.json
    |-- pm2.json     (we will create this in the following steps)
    `-- Dockerfile   (we will create this in the following steps)
⁠Create a pm2 ecosystem file

Create a new file called pm2.json with the following content:

{
  "name": "your-app-name",
  "script": "src/app.js",
  "instances": "2",
  "env": {
    "NODE_ENV": "development"
  },
  "env_production" : {
    "NODE_ENV": "production"
  }
}

You can choose the name of the ecosystem file arbitrarily, but we will assume you called it pm2.json in the following steps.

See the documentation⁠ for more information about how to configure the ecosystem file.

⁠Create a Dockerfile file

Create a new file called Dockerfile with the following content:

FROM keymetrics/pm2:latest-alpine

# Bundle APP files
COPY src src/
COPY package.json .
COPY pm2.json .

# Install app dependencies
ENV NPM_CONFIG_LOGLEVEL=warn
RUN npm install --omit=dev

CMD [ "pm2-runtime", "start", "pm2.json" ]

See the documentation⁠ for more info about the pm2-runtime command.
All options available are listed here⁠.

⁠Build and Run your image

From your Node.js app project folder launch those commands:

$ docker build -t your-app-name .
$ docker run your-app-name

⁠Custom configurations

⁠Enable git auto-pull

If you want to Automatically synchronize your application with git⁠ add this into your Dockerfile:

RUN pm2 install pm2-auto-pull

Make sure the .git is present in your application source folder.

⁠Enable Monitor server

If you want to Automatically monitor vital signs of your server⁠ add this into your Dockerfile:

RUN pm2 install pm2-server-monit
⁠Use Keymetrics.io dashboard

Keymetrics.io⁠ is a monitoring service built on top of PM2 that allows to monitor and manage applications easily (logs, restart, exceptions monitoring, etc...). Once you created a Bucket on Keymetrics you will get a public and a secret key.

To enable Keymetrics monitoring with pm2-runtime, you can whether use the CLI option –public XXXX and –secret YYYY or you can pass the environment variables KEYMETRICS_PUBLIC and KEYMETRICS_SECRET.

From your Node.js app project folder launch those commands:

$ docker build -t your-app-name .
$ docker run -e KEYMETRICS_PUBLIC=XXXX -e KEYMETRICS_SECRET=YYYY your-app-name

Make sure that the port 443 (HTTPS outbound) is allowed on your firewall.

See the troubleshooting⁠ in case you encounter any problem.

⁠Enabling Graceful Shutdown

When the Container receives a shutdown signal, PM2 forwards this signal to your application allowing to close all the database connections, wait that all queries have been processed or that any other final processing has been completed before a successful graceful shutdown.

Catching a shutdown signal is straightforward. You need to add a listener in your Node.js applications and execute anything needed before stopping the app:

process.on('SIGINT', function() {
  db.stop(function(err) {
    process.exit(err ? 1 : 0);
  });
});

By default PM2 will wait 1600ms before sending a final SIGKILL signal. You can modify this delay by setting the kill_timeout option inside your application configuration file.

⁠Expose health endpoint

The --web [port] option allows to expose all vital signs (docker instance + application) via a JSON API.

CMD ["pm2-runtime", "start", "pm2.json", "--web"]

or

CMD ["pm2-runtime", "start", "pm2.json", "--web", "port"]

⁠Useful commands

CommandDescription
$ docker exec -it <container-id> pm2 monitMonitoring CPU/Usage of each process
$ docker exec -it <container-id> pm2 listListing managed processes
$ docker exec -it <container-id> pm2 showGet more information about a process
$ docker exec -it <container-id> pm2 reload all0sec downtime reload all applications

⁠Documentation

The documentation can be found here⁠.

⁠Authors

See also the list of contributors⁠ who participated in this project.

⁠License

This project is licensed under the MIT License - see the LICENSE⁠ file for details.

License information for the software contained in this image can be found here⁠ (pm2) and here⁠ (node).

⁠Development

# Build and test images locally without pushing
./build-and-push.sh --no-push 24-alpine

# Test any image against example-app
bash test/test-image.sh keymetrics/pm2:24-alpine

Tag summary

Content type

Image

Digest

sha256:bac9aea4b…

Size

62.6 MB

Last updated

7 days ago

docker pull keymetrics/pm2