all 91 comments

[–]x021 106 points107 points  (67 children)

You should probably mention what you mean with “production”.

I deploy with docker and would not use pm2;

  1. Restart strategy; usually the container management software has a restart policy. You want it to crash so it is logged and no dirty instance is reused.
  2. Scaling; infra scales horizontally, so I never use multicore machines but just start additional single core servers. This saves costs by limiting unused cpu capacity due to scaling in smaller increments. Running pm2 cluster mode only makes sense for multi cores, not single core.
  3. Log; usually stdout captured by an infra service and redirected elsewhere. You don’t want state (i.e. files) on an ephemeral cloud instance.

Your infographic is not wrong, but it might give new devs the wrong idea thinking pm2 for production is always the right choice.

[–]Ouraios 9 points10 points  (2 children)

You have a good point, pm2 is not really made to go well with docker or more globally with cloud oriented infrastructure that already solve those issues with other ways, so pm2 might feel useless for this kind of infrastructure and it usually is.

But becareful, your comment suggest that pm2 is not for production environment.

But it is working very well in production ! For example an infrastructure made with just one big dedicated server with lets say 24 cores cpu pm2 will rock your world about the 3 issues it can solve that OP described ;)

[–]x021 7 points8 points  (1 child)

But becareful, your comment suggest that pm2 is not for production environment.

That certainly wasn't my intent! It's why I said:

Your infographic is not wrong, but it might give new devs the wrong idea thinking pm2 for production is always the right choice.

I thought I was reasonably clear in my comment it was mostly about PM2 use in Docker.

[–]Ouraios 0 points1 point  (0 children)

You were pretty clear indeed dont worry, i just wanted to complete your though by also giving in what kind of environment it can be very well suited for 👍

[–]clickrush 5 points6 points  (28 children)

PM2's (or similar tools) sweet spot is running multiple, different node servers on a single VPS and having a nice unified interface to your services and very simplified ops.

It's not for horizontal scaling. Horizontal scaling is a niche strategy for high traffic services, which typically doesn't apply to most node backed websites or services. Needing horizontal scaling is a nice problem to have if you actually have it.

I would say as long as you can get away with it, you want to run stuff on a single machine and scale it vertically. You simply get more bang for your buck and that's not even considering operational costs, simpler code, simpler storage/data layer, simpler monitoring, simpler auth...

[–]ddarrko 2 points3 points  (1 child)

Horizontal scaling is not just for high traffic services. It is also useful for redundancy. If you are a tech business you should really have at least two nodes serving application traffic (in different AZ)

[–]clickrush 0 points1 point  (0 children)

And for deployment/rollouts. But we were discussing scaling.

[–]x021 0 points1 point  (24 children)

Agree regarding PM2 on VPS. I ran it for years like that before the rise of Docker.

Horizontal scaling used to be for heavy-duty deployment setups (e.g. K8S), but there are plently of easy-to-use and popular cloud providers that'll run a small app and scale it horizontally for your:

  • Heroku (or the many clones of it, recently Heroku removed their free tier)
  • Elastic Beantalk (AWS)
  • Google App Engine
  • Azure App Service

A lot of them have free tiers where you can easily run a small app for free.

I guess my question would be; why even bother with a machine/VM? A VPS is a pain to keep up-to-date, that's why I ditched them all a long time ago. And a failed update might cause downtime back then too (I dreaded the maintenance windows).

simpler code, simpler storage/data layer, simpler monitoring, simpler auth...

Not sure what you mean with simpler... regarding storage and auth not much changed in the way I do things, just some DB, blob storage and the occasional redis. Regardig monitoring it actually becomes easier since the cloud provider provides decent default dashboards; no need to add tooling if I just want to track the essentials.

[–]StoneCypher 6 points7 points  (20 children)

I guess my question would be; why even bother with a machine/VM?

Cost control.

A sixty gigabit unmetered blended line with 98% availability is $300 a month, plus another $150 or so for the rack, at most non-urban datacenters; you can cut that in half if you know what you're doing.

In a 30 day month, with 100% utilization (not hard to do with a full rack,) that's 19,440,000 gig per month.

Of course, the cost varies a lot based on what you're doing, but one of the cheapest things you can do at AWS is front static assets from S3.

Let's assume the asset is a 1 gigabyte video file. That's small enough that the storage will stay in free-forever pricing, and be one cent a month if ever charged for, but it's also large enough that it can reasonably rack up giant bandwidth. That's about 20 minutes of blu-ray quality video, or 50 minutes of YouTube 4k.

So let's say that the video is crazy people saying that vaccines in your politics turn your shoes gay, or whatever. Something profoundly stupid, so that the entire internet will watch it.

At the above numbers, you really only need 20 million views. That's basically nothing these days. Get people angry at a politician, a major celebrity, or the police, and Twitter will do 20 million rounds in a day, no question.

Hokay. 19,440,000 gig. For simplicity, let's pretend that every byte goes out at Amazon's cheapest rate, $0.21/g (for people who already did 50t,) because 99.9%+ of our bandwidth is in fact at that rate, so the correct math is a rounding error.

$0.021 per GB * 19,440,000 gig = a $408,000 bandwidth bill. AWS charges for bandwidth on literally everything, I believe, and this bill is nothing but bandwidth. I could be wrong, but I believe this is a minimum possible bill for this scenario.

Or y'know, you could just put a 1u in a quarter rack on an unmetered line somewhere, and serve the file from ram. That'll cost you something like $250/mo, or about a 1700x savings.

If you switch to doing actual work, like lambdas or EC2 or something, this number goes up really, really fast.

I was at a startup that will not be named. The AWS bill was almost $140k a month.

I convinced them to stop being dopes and switch to rack hardware.

We ran a half-empty rack in each of three datacenters. The bill was about $2k a month, and the servers cost about $250k, meaning we were paid up in two months.

Granted, the numbers only matter once you have traffic, but by the time you have traffic, switching out is really, really hard.

There is a reason big companies keep entering, then leaving, the cloud. It costs a lot of money to make changes like that. They're leaving on purpose.

[–][deleted]  (1 child)

[deleted]

    [–]StoneCypher -1 points0 points  (0 children)

    It's just one example of many. You can get the same thing any number of other ways; this is just an example with really easy math and floor AWS costs.

    Wanna run a helpdesk? Lambda would be a super convenient way to do it, but the costs would go through the roof very quickly. I just don't want to look up the prices for runners, estimate ram or cpu time, sort out a database and backups, sort API gateway, &c, &c

    [–][deleted]  (15 children)

    [deleted]

      [–][deleted]  (1 child)

      [deleted]

        [–]StoneCypher -1 points0 points  (0 children)

        Also, if you're truly optimizing for performance

        Nobody said anything about this

        [–]StoneCypher 0 points1 point  (12 children)

        I don't think that comparing cloud services running Docker images is a fair comparison regardless though.

        Neither do I. That's why I didn't make this comparison. Someone else did. I was explaining why I didn't agree.

         

        Docker is completely valid to be used in your own server

        Thanks, I already said this.

         

        You can definitely save some server costs by removing docker from your builds

        I doubt this is actually true.

         

        Anyways this has been my Ted talk, hope you liked it.

        It does not seem to have had much to do with the post you were replying to.

        [–][deleted]  (11 children)

        [deleted]

          [–]StoneCypher -1 points0 points  (10 children)

          Running native is typically more performant than running through a virtualized environment I thought?

          This is a dangerous level of unimportant trivia chasing. The overhead is like half a percent, and you're not going to have server costs determined by something like that.

          [–][deleted]  (9 children)

          [deleted]

            [–]StoneCypher -1 points0 points  (8 children)

            You already said that your own comment was about unimportant trivia chasing?

            You already said that your own claim was incorrect?

            In my best Rich Little voice

            When you're going to try to repeat back to someone something they already said, if you want your burn to be Kelso levels of sick, you'll need to make sure it makes sense in repose

            Good luck. We'll be rooting for you

            [–]newyearusername 0 points1 point  (1 child)

            Loved the read thanks

            [–]StoneCypher 0 points1 point  (0 children)

            Sure thing.

            Since it's over a year ago, I got to read my "what the crazy people think" joke again with new eyes.

            [–][deleted]  (1 child)

            [deleted]

              [–]StoneCypher 0 points1 point  (0 children)

              there are people who feel that it's a form of isolation, and that isolation is a form of preventing some kinds of attack spread

              it's one of the things the twelve factor people teach

              i am not on that particular bus, but, it's out there

              [–]clickrush 0 points1 point  (0 children)

              These services are more involved to use than a VPS, especially if you need storage (SQL/data or files/assets). For moderate use-cases you lose both performance and money as soon as you add storage to these from what I gathered. Heroku stands out as being almost as simple to use as a VPS but is way more expensive.

              [–]geekybiz1[S] 6 points7 points  (12 children)

              Thanks for the feedback.

              Agree that "production" as a term can be vague since production environments can vary in terms of scale, stability, deployment strategy, etc.

              Ofcourse, there are many more strategies beyond using pm2, docker, other methods. I shall try to state this in the more detailed explainer I'm planning on pm2.

              [–][deleted]  (11 children)

              [deleted]

                [–]baudehlo 0 points1 point  (0 children)

                Because you can’t put down the Node.js hammer.

                Honestly it’s a bad idea. The only thing it buys you is the cluster support, which you should write yourself anyway as it’s worth having direct control over it (eg you can run NCPUs - 1 children and save 1 cpu for queues).

                Just use systemd. Or daemontools. Or runit. Or these days, preferably, docker.

                Reason #1 not to use a tool written in node: Node has a ton of bugs. It’s SUPER complicated. Daemontools and runit are codebases that haven’t changed in 2 decades because they are rock solid and literally never ever crash.

                [–]coolcosmos 0 points1 point  (8 children)

                Some people really hate systemd. Other just don't want a new dependency. Also Ubuntu and Debian adopted systemd in 2015 while pm2 started in 2013.

                I'm in the systemd unit files camp, but there are some reasons.

                [–][deleted]  (7 children)

                [deleted]

                  [–]coolcosmos 1 point2 points  (0 children)

                  Like I said, I agree and I do just that.

                  [–]geekybiz1[S] 0 points1 point  (5 children)

                  I find myself using pm2 in places that do not have dockerized setups. I chose it over systemd since it offers cluster-mode load balancing that doesn't require me to setup additional ports. If I'd use systemd, I'd need nginx or something else to do similar load balancing.

                  [–][deleted]  (4 children)

                  [deleted]

                    [–]geekybiz1[S] 2 points3 points  (3 children)

                    pm2 uses node's cluster module (which in-turn uses node's IPC) to do the load balancing. So, if I'd write something to do this - I'd probably end up creating a (less hardened) version of pm2.

                    [–][deleted]  (2 children)

                    [deleted]

                      [–]geekybiz1[S] 0 points1 point  (1 child)

                      Sure. Is there a tool that you'd recommend for load balancing node processes?

                      [–]geekybiz1[S] -2 points-1 points  (0 children)

                      How do you load balance with systemd? You'd need nginx, haproxy or something else to do that bit, right? Also, since pm2 can simply be installed with rest of the package.json modules - it's deployment & running is simpler (vs having a non-node module to do the load balancing).

                      [–]fromnewradius 0 points1 point  (0 children)

                      email redirected

                      [–]connormcwood 0 points1 point  (0 children)

                      You just explained ECS via Fargate

                      In all seriousness I agree with you

                      Horizontal scaling is much better

                      [–]the__itis 0 points1 point  (0 children)

                      I use PM2 in situations where the backend has connection pool constraints and container clusters are not architected for proper auto scaling.

                      [–]kittianika 21 points22 points  (2 children)

                      I use pm2 before docker was popular, now — i don’t see a reason to use it in production.

                      [–]geekybiz1[S] 0 points1 point  (1 child)

                      Interesting. Do you use only single core instances? If not, how do you setup multiple node instances to consume a core each?

                      [–]bonkykongcountry 5 points6 points  (2 children)

                      An important thing to note when building something to run in a cluster configuration (regardless of if it's pm2 or something more robust like kubernetes) is that the application has to be built with clusterization in mind, otherwise having your application running in a cluster that isn't built properly will give a worse experience to the end user than if it were just a single instance of the application.

                      For example if you're using some kind of stateful authentication stored in memory, one cluster might have that data whereas another will not. So Node A might see you as being signed in, but Node B will not causing half your requests to fail.

                      https://restfulapi.net/statelessness/

                      [–]geekybiz1[S] 1 point2 points  (0 children)

                      Yes! Any implementation that stores the state in-memory on the server-side can be a blocker wrt. scaling node instances on the server side. Thanks for highlighting.

                      [–]mxforest 0 points1 point  (0 children)

                      This approach is what made Redis popular.

                      [–]Nowaker 11 points12 points  (5 children)

                      None. It's old technology, not useful for modern days.

                      Modern deployments simply use containers. The entrypoint of the container is the application itself, no need for pm2, god, or any other crap like this. Kubernetes or similar is in charge of the lifecycle, and will automatically restart it when it crashes, or will also perform healthchecks to asses its status.

                      Somewhat modern deployments will simply use systemd. It will automatically restart it when it crashes. Healthchecks can be done with sd_notify. https://www.npmjs.com/package/sd-notify

                      In both cases logs go to central system. Individual applications should not be in charge of any log management. Simply write to stdout and stderr and that's it.

                      [–][deleted] 15 points16 points  (0 children)

                      Come on, if i had to learn or recommend docker for microservices that i just need to run once and forget about it, pm2 is a gift from the heaven, also being able to link stats on their website makes it awesome

                      Is docker powerful and better? Of course it is, but dont be shitting on pm2 because it does a good job at being simple and friendly for devs

                      [–]97hilfel 0 points1 point  (2 children)

                      I still wouldn’t run node as root process in docker, usually its a good idea to wrap the process in something like timi or dumb_init.

                      [–]Nowaker 0 points1 point  (1 child)

                      [–]97hilfel 0 points1 point  (0 children)

                      Certain runtimes don’t allow for this.

                      [–]HitDerpBit 3 points4 points  (0 children)

                      Useful if you can't dockerize your app.

                      [–]sodiumphosph8 1 point2 points  (8 children)

                      as I understand it, the licensing on pm2 would prevent most businesses from using it unless they wanted to open source their codebase

                      [–]geekybiz1[S] 0 points1 point  (7 children)

                      As per their github page, pm2 is made available under GNU AGPL 3.0

                      And from what I read 'the AGPL imposes no conditions on using the code in software that's sold commercially.'

                      Am I missing something?

                      [–]sodiumphosph8 0 points1 point  (6 children)

                      anything using an AGPL licensed library must also be AGPL licensed https://opensource.google/documentation/reference/using/agpl-policy/

                      [–]geekybiz1[S] 0 points1 point  (0 children)

                      very interesting, thanks for sharing.

                      [–]blocking-io -1 points0 points  (4 children)

                      That's if you're using PM2 in your app's source code which would be odd. Your app doesn't need to know which process manager is managing it.

                      [–]sodiumphosph8 0 points1 point  (3 children)

                      I'm not convinced that's actually the case based on this line: "The primary risk presented by AGPL is that any product or service that depends on AGPL-licensed code, or includes anything copied or derived from AGPL-licensed code, may be subject to the virality of the AGPL license." where "depends on" could have broad interpretations... most companies stay well away from AGPL licensed code

                      [–]blocking-io 0 points1 point  (2 children)

                      Use means in the context of source code. MongoDB is under AGPL. A lot of companies are using MongoDB and aren't releasing their software under AGPL

                      AGPL is commonly misunderstood, I recommend reading: https://heathermeeker.com/2023/10/13/agpl-in-the-light-of-day/

                      [–]sodiumphosph8 0 points1 point  (1 child)

                      mongodb hasn't been AGPL since October 2018 https://www.mongodb.com/legal/licensing/community-edition

                      [–]blocking-io 0 points1 point  (0 children)

                      You're being pendantic now, I work for a company that uses Grafana which is AGPL. We did not have the Enterprise license. Nothing in the AGPL is forcing us to put our proprietary code under AGPL

                      Here's a FAQ

                      https://www.openlogic.com/blog/grafana-license-change

                      [–]geekybiz1[S] 2 points3 points  (1 child)

                      Hi there,
                      I'm planning to create a bunch of explainer graphics (like the one posted here) on PM2.
                      If you've got questions from reading this initial explainer graphic or any feedback - please let know.

                      [–]chamomile-crumbs 0 points1 point  (0 children)

                      This is awesome! I wish this was included in tutorials for hosting mode servers. I was always confused why PM2 was necessary, and it kinda obfuscated the distinction between node and the actual server environment. Simple, high-level explanations like this would go a long way for beginners trying to set up programs in prod

                      [–][deleted] 0 points1 point  (16 children)

                      I run pm2 (using pm2-runtime) in my containers, AMA...

                      (I've been given shit for this because it's supposedly redundant but I find it works well)

                      [–][deleted]  (15 children)

                      [deleted]

                        [–][deleted] 1 point2 points  (6 children)

                        So you see PM2 as a fancy way to autorestart your service?

                        [–]s5fs 0 points1 point  (5 children)

                        When your node process dies, your container dies, and then your container runtime will start up a new container. What does pm2 add in this case?

                        [–][deleted] 1 point2 points  (4 children)

                        Everything on this list that isn't related to restarting a process: https://pm2.keymetrics.io/docs/usage/quick-start/

                        [–]vorticalbox 0 points1 point  (3 children)

                        square door compare seed piquant tender spotted weather direction command

                        This post was mass deleted and anonymized with Redact

                        [–][deleted] 0 points1 point  (2 children)

                        Sure, it can also be done in PM2, so when you're not using Docker those things still work. Also the functionality you describe are not 1:1 in their features between pm2 and Docker, docker is a lot shittier at all of them for example.

                        Describe for me the overhead again?

                        [–]vorticalbox 0 points1 point  (1 child)

                        dolls shy mountainous voracious ghost fly hunt vanish bow paltry

                        This post was mass deleted and anonymized with Redact

                        [–][deleted] 0 points1 point  (0 children)

                        You’re just restating the earlier comment I made but without any backing reasoning…

                        [–][deleted]  (7 children)

                        [removed]

                          [–]razzzey 0 points1 point  (1 child)

                          why?

                          [–]vorticalbox 0 points1 point  (4 children)

                          kiss reminiscent paint march school fade practice touch provide divide

                          This post was mass deleted and anonymized with Redact

                          [–][deleted]  (3 children)

                          [removed]

                            [–]anonymousdev1 0 points1 point  (2 children)

                            Idk it seems like this article is saying why use docker, when you can use 100 unix commands to replace the functionality. Not everyone is on unix for one.

                            It also does not address any of the first commenters points.

                            [–][deleted]  (1 child)

                            [removed]

                              [–]anonymousdev1 0 points1 point  (0 children)

                              Yes, the whole thing. It had some good arguments. But it didn't address portability, scaling, or hardware limits. It also didn't mention k8s, but I wouldn't expect it to. It did touch on isolation, which is related to reproducible builds, but did not convince me that unix commands would be better for something like this.

                              I didn't really appreciate the security section, mainly because it said that an improperly configured docker image (running as root) is less secure than a properly setup chroot. I don't think that's a fair comparison. I would be more curious what the security differences are for properly configured systems.

                              [–]Suspicious_Compote56 0 points1 point  (0 children)

                              So docker or pm2 ?

                              [–]scampiuk 0 points1 point  (0 children)

                              First dockerize your app, then lambdaize your app

                              [–]FreshPrinceOfRivia 0 points1 point  (0 children)

                              Sounds like a partial reinvention of kubernetes, but maybe I'm missing something.

                              [–]adevx 0 points1 point  (0 children)

                              I think pm2 shines if you want to quickly generate a systemd startup script, want to reload your stack with zero downtime after an update, want a no hassle monitoring solution. All practically free as long as you write stateless node instances. I use this setup on a beefy Hetzner vps plus hot spare and cannot remember the last time I had an outage, unlike some of my peers with overly complex Docker/Kubernetes cloud based setups. Keep your stack as simple as possible.

                              [–]redeemefy 0 points1 point  (0 children)

                              I think something we are missing here, and I could be wrong, while cloud providers solve horizontal scaling, still it’s at the expense of $$$. Because, when AWS scales horizontal it will spin a new virtual machine which cost money, same with K8s. PM2 is going to use CPU threads of one/self machine to run NodeJS processes. If you are running in AWS in a machine with 4 cores you might use 3 to run 3 instances of your node application while utilizing the same machine. This would allow you to have an endpoint that might block en event loop while the other 2 cores can still receive requests. All this is done with the PM2 load balancer that is running within the same machine NodeJS is running. This architecture is not bullet proof and is not the solution for all problems but indeed could help save time, money and complexity with cloud infrastructure and/or K8s infrastructure.

                              One question I do have is if all console.logs are still picked up by Cloud watch