eduardweb.
PM2 & NodeIntermediar#devops#pm2#node-js#javascript

PM2 în producție: Configurare corectă cu ecosystem.config.js și zero-downtime

De Sorin Tudor, 11 iun. 2026 · 20 vizualizări · 3 like-uri

Postat 11 iun. 2026
javascript
module.exports = {
  apps: [{
    name: "api-prod",
    script: "./dist/server.js",
    instances: "max",
    exec_mode: "cluster",
    watch: false,
    max_memory_restart: "500M",
    env: {
      NODE_ENV: "production",
      PORT: 3000
    },
    error_file: "./logs/err.log",
    out_file: "./logs/out.log",
    merge_logs: true,
    listen_timeout: 8000,
    kill_timeout: 3000
  }]
};

Salutare. Am văzut prea mulți developeri care dau pm2 start server.js direct în producție și apoi se miră de ce le crapă aplicația la primul spike mai serios de trafic sau de ce s-a blocat VPS-ul fiindcă s-a umplut discul de loguri. Dacă rulezi Node.js fără un fișier de configurare dedicat, practic mergi la noroc.

Am trecut prin asta acum vreo trei ani, la un proiect cu vreo 15k useri activi zilnic. Serverul murea subit o dată pe săptămână din cauza unui memory leak stupid de la o librărie de randat PDF-uri. Trecerea la un ecosystem.config.js bine pus la punct ne-a salvat nopțile de weekend și ne-a redus stresul la zero.

Cluster Mode și Graceful Reload fără downtime

Node.js rulează single-threaded. Dacă ai un server cu 4 sau 8 nuclee și pornești aplicația în modul fork (cel default), folosești doar un singur nucleu, adică irosești masiv resursele pentru care plătești. Prin modul cluster, PM2 multiplică instanțele aplicației pe toate nucleele disponibile.

Marele avantaj? Zero-downtime deployment. Când dai pm2 reload all, PM2 repornește procesele pe rând. În timp ce primul proces se restartează, celelalte preiau traficul. Utilizatorul final nu va vedea nici măcar o secundă de eroare 502.

Dar atenție la trade-off: aplicația ta trebuie să fie stateless. Dacă ții sesiunile utilizatorilor în memoria RAM a procesului (în loc de un magazin de sesiuni precum Redis) sau dacă folosești WebSockets fără un adaptor extern, userii vor fi deconectați aleatoriu când request-ul lor ajunge pe alt nucleu.

Cum gestionăm Out of Memory (OOM)

Node.js are prostul obicei să mănânce memorie până când sistemul de operare îi dă kill direct prin OOM Killer. Pe un VPS mic de 2GB RAM, asta înseamnă că tot serverul poate deveni instabil și restul serviciilor (cum ar fi baza de date locală) pot pica.

Prin opțiunea max_memory_restart, îi spunem lui PM2: „Dacă procesul ăsta sare de 500MB, dă-i un restart curat”. Da, e un workaround, nu rezolvă bug-ul din spatele leak-ului de memorie, dar măcar producția rămâne în picioare în timp ce tu investighezi liniștit problema în local.

Logurile: ucigașul tăcut al discului de stocare

Dacă nu configurezi destinația logurilor, PM2 le scrie implicit într-un singur fișier ascuns din folderul home al utilizatorului. Am pățit ca un server de staging să rămână fără spațiu pe disc (100% full) din cauza unui singur fișier de log de 45GB, plin de warning-uri inutile de la o bază de date.

Soluția este să definim clar rutele de loguri în config și să instalăm global modulul de rotație din consolă: pm2 install pm2-logrotate

Acesta va tăia automat logurile zilnic sau când ating o anumită dimensiune (de exemplu, 10MB) și va păstra doar ultimele 30 de zile. Configurația din exemplul de cod combină logurile tuturor instanțelor din cluster într-un singur fișier, făcând debugging-ul mult mai simplu.

Tu cum îți gestionezi aplicațiile de Node în producție? Mergi pe varianta clasică cu PM2 direct pe VPS sau ai trecut deja totul în containere Docker orchestrate de Kubernetes?

Răspunsuri 0

Se încarcă răspunsurile…

Loghează-te pentru a răspunde

Doar membrii comunității pot lăsa comentarii.