menu

Using PM2 with Docker

Production ready Node.js Docker image including PM2.

The goal of pm2-runtime 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:

  • Second Process Fallback for High Application Reliability
  • Process Flow Control
  • Automatic Application Monitoring to keep it always sane and high performing
  • Automatic Source Map Discovery and Resolving Support

Further than that, using PM2 as a layer between the container and the application brings PM2 powerful features like ecosystem file, custom log system and other features of pm2.

Prepare your app

Tags available

Image Name Operating system Dockerfile
keymetrics/pm2:latest-alpine Alpine latest-alpine
keymetrics/pm2:8-alpine Alpine 8-alpine
keymetrics/pm2:6-alpine Alpine 6-alpine
keymetrics/pm2:4-alpine Alpine 4-alpine
Image Name Operating system Dockerfile
keymetrics/pm2:latest-stretch Debian Stretch latest-stretch
keymetrics/pm2:8-stretch Debian Stretch 8-stretch
keymetrics/pm2:6-stretch Debian Stretch 6-stretch
keymetrics/pm2:4-stretch Debian Stretch 4-stretch
Image Name Operating system Dockerfile
keymetrics/pm2:latest-jessie Debian Jessie latest-jessie
keymetrics/pm2:8-jessie Debian Jessie 8-jessie
keymetrics/pm2:6-jessie Debian Jessie 6-jessie
keymetrics/pm2:4-jessie Debian Jessie 4-jessie
Image Name Operating system Dockerfile
keymetrics/pm2:latest-slim Debian Jessie (minimal packages) latest-slim
keymetrics/pm2:8-slim Debian Jessie (minimal packages) 8-slim
keymetrics/pm2:6-slim Debian Jessie (minimal packages) 6-slim
keymetrics/pm2:4-slim Debian Jessie (minimal packages) 4-slim
Image Name Operating system Dockerfile
keymetrics/pm2:latest-wheezy Debian Wheezy latest-wheezy
keymetrics/pm2:8-wheezy Debian Wheezy 8-wheezy
keymetrics/pm2:6-wheezy Debian Wheezy 6-wheezy
keymetrics/pm2:4-wheezy Debian Wheezy 4-wheezy

You can find more information about the image variants here.

The build process of these images is automatically triggered each time NodeJS’s Docker images are built.
The build process of these images is automatically triggered each time Docker PM2’s GitHub repo master branch is pushed.
The build process of these images is automatically triggered each time PM2’s GitHub repo master branch is pushed.

Usage

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

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

Set your ecosystem file

Generate an ecosystem.config.js template with:

pm2 init

Modify the ecosystem file to match your needs:

module.exports = {
  apps : [{
    name: "app",
    script: "./app.js",
    env: {
      NODE_ENV: "development",
    },
    env_production: {
      NODE_ENV: "production",
    }
  }]
}

Learn more about ecosystem file here.

Set a Dockerfile

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 ecosystem.config.js .

# Install app dependencies
ENV NPM_CONFIG_LOGLEVEL warn
RUN npm install --production

# Expose the listening port of your app
EXPOSE 8000

# Show current folder structure in logs
RUN ls -al -R

CMD [ "pm2-runtime", "start", "ecosystem.config.js" ]

Build your image

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

docker build -t your-app-name .

Run your image

docker run -p 80:8000 your-app-name

-p 80:8000 binds the port 8000 of your app to the port 80 of the localhost

pm2 commands

pm2 commands can still be used inside a container with the docker exec command:

# Monitoring CPU/Usage of each process
docker exec -it <container-id> pm2 monit
# Listing managed processes
docker exec -it <container-id> pm2 list
# Get more information about a process
docker exec -it <container-id> pm2 show
# 0sec downtime reload all applications
docker exec -it <container-id> pm2 reload all

Expose health endpoint

CMD ["pm2-runtime", "ecosystem.config.js", "--web"]

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

After installing pm2 in your shell, run pm2-runtime -h to get all options available

You are ready

That’s all! Your container is ready to be deployed.

Next Steps

Complete your configuration with the Ecosystem File.

Monitor your app on a web dashboard, with PM2 Plus.