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.
Image Name | Operating system | Dockerfile |
---|---|---|
keymetrics/pm2:latest-alpine |
Alpine | latest-alpine |
keymetrics/pm2:18-alpine |
Alpine | 15-alpine |
keymetrics/pm2:16-alpine |
Alpine | 15-alpine |
keymetrics/pm2:15-alpine |
Alpine | 15-alpine |
keymetrics/pm2:14-alpine |
Alpine | 14-alpine |
keymetrics/pm2:12-alpine |
Alpine | 12-alpine |
keymetrics/pm2:10-alpine |
Alpine | 10-alpine |
Image Name | Operating system | Dockerfile |
---|---|---|
keymetrics/pm2:latest-buster |
Debian Buster | latest-buster |
keymetrics/pm2:18-buster |
Debian Buster | 18-buster |
keymetrics/pm2:16-buster |
Debian Buster | 16-buster |
keymetrics/pm2:15-buster |
Debian Buster | 15-buster |
keymetrics/pm2:14-buster |
Debian Buster | 14-buster |
keymetrics/pm2:12-buster |
Debian Buster | 12-buster |
keymetrics/pm2:10-buster |
Debian Buster | 10-buster |
Image Name | Operating system | Dockerfile |
---|---|---|
keymetrics/pm2:latest-stretch |
Debian Stretch | latest-stretch |
keymetrics/pm2:18-stretch |
Debian Stretch | 18-stretch |
keymetrics/pm2:16-stretch |
Debian Stretch | 16-stretch |
keymetrics/pm2:15-stretch |
Debian Stretch | 15-stretch |
keymetrics/pm2:14-stretch |
Debian Stretch | 14-stretch |
keymetrics/pm2:12-stretch |
Debian Stretch | 12-stretch |
keymetrics/pm2:10-stretch |
Debian Stretch | 10-stretch |
Image Name | Operating system | Dockerfile |
---|---|---|
keymetrics/pm2:latest-jessie |
Debian Jessie | latest-jessie |
keymetrics/pm2:18-jessie |
Debian Jessie | 18-jessie |
keymetrics/pm2:16-jessie |
Debian Jessie | 16-jessie |
keymetrics/pm2:15-jessie |
Debian Jessie | 15-jessie |
keymetrics/pm2:14-jessie |
Debian Jessie | 14-jessie |
keymetrics/pm2:12-jessie |
Debian Jessie | 12-jessie |
keymetrics/pm2:10-jessie |
Debian Jessie | 10-jessie |
Image Name | Operating system | Dockerfile |
---|---|---|
keymetrics/pm2:latest-slim |
Debian Stretch (minimal packages) | latest-slim |
keymetrics/pm2:18-slim |
Debian Stretch (minimal packages) | 18-slim |
keymetrics/pm2:16-slim |
Debian Stretch (minimal packages) | 16-slim |
keymetrics/pm2:15-slim |
Debian Stretch (minimal packages) | 15-slim |
keymetrics/pm2:14-slim |
Debian Stretch (minimal packages) | 14-slim |
keymetrics/pm2:12-slim |
Debian Stretch (minimal packages) | 12-slim |
keymetrics/pm2:10-slim |
Debian Stretch (minimal packages) | 10-slim |
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.
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 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 itpm2.json
in the following steps.
See the documentation for more information about how to configure the ecosystem
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 --production
# Show current folder structure in logs
RUN ls -al -R
CMD [ "pm2-runtime", "start", "pm2.json" ]
See the documentation for more info about the pm2-runtime
command.
All options available are listed here.
From your Node.js app project folder launch those commands:
$ docker build -t your-app-name .
$ docker run your-app-name
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.
If you want to Automatically monitor vital signs of your server add this into your Dockerfile:
RUN pm2 install pm2-server-monit
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 ports 80 (TCP outbound), 443 (HTTPS outbound) and 43554 (TCP outbound) are allowed on your firewall.
See the troubleshooting in case you encounter any problem.
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.
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"]
Command | Description |
---|---|
$ docker exec -it <container-id> pm2 monit |
Monitoring CPU/Usage of each process |
$ docker exec -it <container-id> pm2 list |
Listing managed processes |
$ docker exec -it <container-id> pm2 show |
Get more information about a process |
$ docker exec -it <container-id> pm2 reload all |
0sec downtime reload all applications |
The documentation can be found here.
See also the list of contributors who participated in this project.
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).