what is the point of using pm2 and docker together?
Asked Answered
T

3

150

We have been using pm2 quite successfully for running apps on our servers. We are currently moving to docker and we saw http://pm2.keymetrics.io/docs/usage/docker-pm2-nodejs/

But what is the point of actually using both together? Does not docker provide everything pm2 does?

Transferor answered 5/7, 2018 at 12:30 Comment(0)
B
239

Usually there is no point in using pm2 inside of a docker.

Both PM2 and Docker are process managers and they both can do log forwarding, restart crashed workers and many other things. If you run pm2 inside of a docker container you will hide potential issues with your service, at least following:

1) If you run a single process per container with pm2 you will not gain much except for increased memory consumption. Restarts can be done with pure docker with a restart policy. Other docker based environments (like ECS or Kubernetes) can also do it.

2) If you run multiple processes you will make monitoring harder. CPU/Memory metrics are no longer directly available to your enclosing environment.

3) Health checks requests for a single PM2 process will be distributed across workers which is likely to hide unhealthy targets

4) Worker crashes are hidden by pm2. You will hardly ever know about them from your monitoring system (like CloudWatch).

5) Load balancing becomes more complicated since you're virtually going to have multiple levels of load balancing.

Also running multiple processes inside of a docker container contradicts the philosophy of docker to keep a single process per container.

One scenario I can think of is if you have very limited control over your docker environment. In this case running pm2 may be the only option to have control over worker scheduling.

Bred answered 19/3, 2019 at 16:11 Comment(7)
The only thing I can add is that from "Top 4 Tactics To Keep Node.js Rockin’ in Docker" docker.com/blog/keep-nodejs-rockin-in-docker also advised against using pm2 inside docker.Metz
For #2: doesn’t PM2 have the monitoring feature? For #3: doesn’t PM2 resurrect unhealthy/dead processes? I’m planning to put a PM2-Node.js-cluster into a container that gets all traffic, so load-balancing gets more simpler. Is it that bad?Ammeter
Depending on your environment. If you plan to "directly" expose your pm2 cluster, then it may work. However, if you have something like ECS + ALB and autoscaling, it will hardly make sense to use pm2.Bred
If your web app has files that change overtime like CSV files that it relies on then the Docker runtime by itself won't monitor those files for changes. Pm2 will reload the app when specific files change which some use cases require.Bunch
@Qiulang's link to docker.com is dead, but it's available on Internet Archive: web.archive.org/web/20220107053002/https://www.docker.com/blog/…Fulk
I think it takes much more resources to run without pm2. It will require around 4x more containers per CPU core.Lodged
How about 'running multiple pm2 processes in a single Docker container'? Use docker as a virtual environment and manage instances with pm2?Cyton
S
66

update:

you may not be in favour of using pm2 inside Docker but sometimes the application requirements are different and you may need to run two nodejs application in one docker container, so in case if you want to run frontend and backend application in the same container then in the case pm2 work well then other workarounds.

So now we have pm2-runtime which run the docker process in the foreground, your application will be running the foreground with pm2 and you can expect the same result as running without pm2.

So with pm2-run time

  • You can run multiple node application in the Docker container
  • You can run the application now in the foreground
  • You can integrate with key metrics
  • You produce custom metrics
  • the same behaviour of the container as without pm2 but with pm2 have some these advantages.
  • You can now control the restart behaviour, ( if a process crash the pm2 will do an auto restart, if disabled then the container will be terminated)
  • In development environment like in mounting you do not need to restart container but just restart the pm2 processes pm2 restart all , which will save time development.
FROM node:alpine
RUN npm install pm2 -g
CMD ["pm2-runtime", "app.js"]

or If you want to run multiple node application in a container then you can process.yml

FROM node:alpine
RUN npm install pm2 -g
CMD ["pm2-runtime", "process.yml"]

process.yml file You can also create an Ecosystem file in YAML format. Example:

This will allow the container to run multiple nodejs processed.

apps:
  - script   : ./api.js
    name     : 'api-app'
    instances: 4
    exec_mode: cluster
  - script : ./worker.js
    name   : 'worker'
    watch  : true
    env    :
      NODE_ENV: development
    env_production:
      NODE_ENV: production

If you want to run with Keymetrics.

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

enter image description here

FROM node:alpine
RUN npm install pm2 -g
CMD ["pm2-runtime", "--public", "XXX", "--secret", "YYY", "process.yml"]

Disable Auto restart:

With this flag, the container will be killed if the nodejs process killed or stopped due to an error or exception. Sometimes we do not auto restart the process but we want to restart the container.

FROM node:alpine
RUN npm install pm2 -g
CMD ["pm2-runtime","app.js","--no-autorestart"]

Without pm2 runtime

As a rule of thumb only one process per container. So keeping this in mind you start your process inside the container using node start server.js as you did without docker. What will happens here if nodejs server crash? your container will be killed in this case. which one should avoid doing this.

Your container will be killed whenever the nodejs server goes down because the primary process will go down and that process should be in the foreground as being the primary process of the container.

So ultimately there is pm2 for that. This is how you can use pm2 and supervisord together to achieve that.

If you are also looking for an example, Here is the dockerfile and required config file. Using the alpine most lightweight image of 2MB.

FROM alpine:3.7
COPY supervisord.conf /etc/supervisord.conf
#installing nodejs and supervisord
RUN apk add  --no-cache --repository http://dl-cdn.alpinelinux.org/alpine/v3.7/main/ \
    --repository http://dl-cdn.alpinelinux.org/alpine/v3.7/community/ \  
   sudo supervisor nodejs>=8 
RUN npm i pm2  -g
COPY pm2.conf  /etc/supervisord.d/pm2.conf

supervisord.conf

[unix_http_server]
file = /tmp/supervisor.sock
chmod = 0777
chown= nobody:nogroup

[supervisord]
logfile = /tmp/supervisord.log
logfile_maxbytes = 50MB
logfile_backups=10
loglevel = info
pidfile = /tmp/supervisord.pid
nodaemon = true
umask = 022
identifier = supervisor

[supervisorctl]
serverurl = unix:///tmp/supervisor.sock

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[include]
files = /etc/supervisord.d/*.conf

pm2.conf

    [supervisord]
    nodaemon=true
    
    [program:pm2]
    command:pm2 start pm2_processes.yml --no-daemon
    startretries:5

Subsume answered 5/7, 2018 at 13:7 Comment(9)
"which one should avoid doing this." Docker Swarm could handle thisOldenburg
Yes you can ignore it, it's same as pm2 start server.Js. You can read about yml config here pm2.keymetrics.io/docs/usage/application-declarationSubsume
seems like the correct folder is /etc/supervisor/conf.d/ not /etc/supervisord.d/ ?? gist.github.com/RoccoHoward/4440d9ac0a375665de0c9c2068a53715Footboy
you need two folder, one for global config that /etc/supervisord.conf and for application config that is ` /etc/supervisord.d/pm2.conf`Subsume
The pm2 site says to use pm2-runtime instead of pm2. I'm not sure what the difference is, or how to get isnight into status and logging.Indic
Pm2 runtime just keep running the progress in foreground so it's better to run with pm2 run timeSubsume
@Indic answer is updated. Thanks for the comment and for pm2 runtimeSubsume
@Subsume I still don't understand why we need pm2 & supervisord together, can't pm2 alone does the job ? BTW I also asked a related question about pm2 & supervisord #68357317Metz
The problem is that you are now running the container as root, right? How can we prevent this from happening? @SubsumeTole
H
4

I guess this could be useful when running AWS Elastic Beanstalk on a single instance without a load balancer.

If you're using EB without a load balancer and there's a fatal error in the docker container, it exits and EB doesn't restart it, leaving you with a broken app, as discussed in my question on the topic. By running pm2 in the container, you can avoid this and have the container restart itself.

The question now becomes, "couldn't I just use pm2 without Docker?" The answer is yes, but you could still benefit from the abstractions that Docker provides, so it might make sense to use both Docker and pm2.

Harve answered 11/3, 2023 at 5:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.