Skip to Content

Chapitre 9.3 — PM2, l’alternative

⏱️ TL;DRPM2 est le gestionnaire de process historique et populaire de l’écosystème Node. Il fait ce que systemd fait — garder ton app vivante, la relancer, capturer ses logs — mais avec une ergonomie pensée pour Node : un ecosystem.config.js versionné, le mode cluster (plusieurs instances sur tes cœurs, en une option), du monitoring intégré (pm2 monit), et un pm2 reload sans coupure. Point crucial : pour survivre au reboot, PM2 s’appuie quand même sur systemd (pm2 startup génère un service). La recommandation de ce cours : systemd par défaut (déjà là, standard, un seul système à connaître) ; PM2 si tu gères beaucoup d’apps Node ou veux le cluster clé en main.

🎯 Objectifs

  • Installer et lancer une app Node avec PM2 (pm2 start, ecosystem.config.js).
  • Rendre PM2 persistant au boot (pm2 startup + pm2 save) — et comprendre que ça repose sur systemd.
  • Utiliser le cluster mode et le reload sans coupure.
  • Comparer honnêtement systemd et PM2, et choisir en connaissance de cause.

Ce qu’est PM2 (et ce qu’il n’est pas)

PM2 est un process manager écrit en Node, installé globalement, qui supervise une ou plusieurs apps Node. Il garde un démon en tâche de fond qui surveille tes process, les relance s’ils tombent, agrège leurs logs et expose des commandes très lisibles.

Ce qu’il n’est pas : un remplaçant complet de systemd. Le démon PM2 doit lui-même être relancé au boot — et pour ça, PM2… génère un service systemd. Autrement dit, PM2 s’ajoute à systemd, il ne s’y substitue pas. C’est une couche d’ergonomie Node au-dessus du mécanisme d’init.

Démarrer avec PM2

# Installer PM2 globalement (npm, mais pnpm/yarn marchent aussi) sudo npm install -g pm2 pm2 -v # Lancer l'app (npm start = "next start -p 3000" dans package.json) cd /var/www/formacampus pm2 start npm --name formacampus-web -- start # "npm" = le binaire lance ; --name nomme le process ; -- start passe "start" a npm pm2 status # tableau des process geres (etat, CPU, RAM, restarts) pm2 logs formacampus-web # logs en direct

pm2 status te donne un tableau immédiatement lisible : nom, état (online), CPU, mémoire, nombre de redémarrages. C’est l’une des raisons de sa popularité : le confort visuel.

Le fichier ecosystem.config.js : la config versionnée

Lancer avec des arguments en ligne de commande, c’est bien pour tester. En vrai, on versionne la configuration dans un fichier ecosystem.config.js à la racine du projet. Il décrit quoi lancer, comment, avec quelles variables — l’équivalent PM2 d’un unit systemd, mais dans ton repo.

// ecosystem.config.js module.exports = { apps: [ { name: 'formacampus-web', script: 'npm', args: 'start', // lance "npm start" cwd: '/var/www/formacampus', // dossier de travail instances: 1, // 1 = un process ; "max" = cluster (voir plus bas) exec_mode: 'fork', // "fork" (1 instance) ou "cluster" env: { NODE_ENV: 'production', PORT: 3000, }, max_memory_restart: '500M', // relance l'instance si elle depasse 500 Mo }, ], }
pm2 start ecosystem.config.js # lance tout ce que le fichier decrit pm2 restart ecosystem.config.js # redemarre apres un deploiement

💡 Réflexe — Versionne l’ecosystem.config.js dans le repo, mais jamais les secrets dedans. Mets-y le non-secret (NODE_ENV, PORT) et charge les secrets depuis un .env hors git (PM2 sait lire un fichier d’env, ou ton app le charge elle-même). Un ecosystem.config.js avec un mot de passe de base committé, c’est la même fuite que le piège NEXT_PUBLIC_ du chapitre 9.1 — mais côté serveur.

Survivre au reboot : pm2 startup + pm2 save

Voici le point que beaucoup ratent. Lancer une app avec PM2 ne la fait pas remonter au boot toute seule — le démon PM2 lui-même s’éteint au reboot. Il faut deux commandes.

# 1. Genere et installe un service systemd qui relancera PM2 au boot pm2 startup # -> PM2 affiche une commande "sudo env PATH=... pm2 startup systemd -u deploy ..." # a copier-coller telle quelle. Elle cree le service systemd de PM2. # 2. Fige la liste des process actuels pour que PM2 les restaure au demarrage pm2 save # -> sauvegarde l'etat courant ; c'est CE qui sera relance au boot

Retiens l’ironie : PM2 utilise systemd pour survivre au reboot. pm2 startup génère un unit systemd. Donc même en PM2, tu ne coupes pas à systemd — tu ajoutes juste une couche.

⚠️ Piège — Oublier pm2 save (ou l’oublier après avoir changé la liste des apps). pm2 startup installe le service, mais c’est pm2 save qui fige la liste des process à restaurer. Sans lui, PM2 remonte au boot… sans aucune app. Et si tu ajoutes une app plus tard sans refaire pm2 save, elle ne reviendra pas après un reboot. Réflexe : tout changement de process → pm2 save.

Ce que PM2 apporte en plus : cluster et reload

Deux fonctionnalités justifient à elles seules le choix de PM2 pour certains.

Le mode cluster. Node est mono-thread : un seul process n’exploite qu’un cœur. PM2 peut lancer plusieurs instances de ton app derrière un load balancer interne, une par cœur, en une option. Ta machine a 4 vCPU ? Quatre instances qui se partagent la charge, sans config réseau.

# Lancer autant d'instances que de coeurs disponibles pm2 start npm --name formacampus-web -i max -- start # -i max : mode cluster, une instance par coeur CPU

Le reload sans coupure. pm2 reload redémarre les instances une par une, en gardant toujours au moins une qui répond. Résultat : un déploiement sans aucune requête perdue (on approfondit le zéro-downtime au chapitre 9.5).

pm2 reload formacampus-web # recharge sans coupure (vs restart qui coupe brievement)

💡 Réflexe — Le cluster mode n’a de sens que si ton app est stateless (pas d’état en mémoire partagé entre requêtes : sessions en base ou en Redis, pas dans une variable globale). Sinon, deux instances ne verront pas les mêmes données et tu auras des bugs aléatoires. Pour du Next.js SSR classique (stateless par nature), c’est parfait ; pour une app qui garde de l’état en RAM, réfléchis avant.

systemd vs PM2 : la comparaison honnête

Les deux résolvent le même problème (garder l’app vivante). Le choix est une affaire de contexte, pas de « meilleur outil » absolu.

CritèresystemdPM2
Déjà installéOui (natif Linux)Non (npm i -g pm2)
PortéeTous les services (Node, Postgres, Nginx…)Node uniquement
Survie au bootNative (enable)Via systemd (pm2 startup)
Survie au crashRestart=alwaysNative
Cluster multi-cœursManuel (plusieurs units / socket)Une option (-i max)
Reload sans coupureDépend de l’appNatif (pm2 reload)
Monitoring intégrésystemctl/journalctl (sobre)pm2 monit, dashboard (riche)
Configunit .service dans /etcecosystem.config.js dans le repo
Courbe d’apprentissageÀ connaître de toute façonUne couche de plus
Un seul système à maîtriserOuiNon (PM2 + systemd dessous)

La recommandation de ce cours :

  • systemd par défaut. Il est déjà là, c’est le standard Linux, il gère tous tes services de la même façon (ton app, ta base, Nginx), et tu dois de toute façon le connaître. Un serveur, un système d’init à maîtriser. Pour une app Next.js, systemd est le choix sobre et suffisant.
  • PM2 si tu gères beaucoup d’apps Node sur la même machine (son tableau de bord et son ergonomie deviennent un vrai confort), ou si tu veux le cluster mode et le reload clé en main sans bricoler systemd.

⚠️ Piège — Faire tourner la même app sous systemd et PM2 en même temps. Les deux vont vouloir la démarrer, se disputer le port 3000 (EADDRINUSE), et tu auras des redémarrages en boucle incompréhensibles. Choisis-en un. Si tu migres de PM2 vers systemd (ou l’inverse), pm2 delete (ou systemctl disable --now) l’ancien avant d’activer le nouveau.

🔒 Sécurité — Comme pour systemd, ne fais pas tourner PM2 en root. Installe et lance-le sous deploy, et lorsque pm2 startup te donne sa commande, vérifie qu’elle cible bien -u deploy (pas root). Une app Node compromise sous root, c’est la machine entière ouverte ; sous deploy, les dégâts restent confinés.

🧭 Sur FormaCampus — L’équipe FormaCampus n’a qu’une app Node (le front) et une API Symfony (pas Node). Elle reste sur systemd : un seul système d’init à opérer pour formacampus-web, formacampus-api et Postgres, pas d’outil supplémentaire à installer et surveiller. Le jour où elle multiplierait les micro-services Node (un worker de mails, un service de recherche, un renderer PDF…), PM2 et son tableau de bord pm2 monit deviendraient un vrai gain de confort — et le cluster mode l’aiderait à saturer les cœurs du VPS. Mais aujourd’hui, systemd suffit : on n’ajoute pas une dépendance sans besoin.

📚 La doc — La doc officielle PM2 (site pm2.keymetrics.io) détaille l’ecosystem.config.js, le cluster, le deploy intégré et le monitoring. Attention : PM2 pousse aussi une offre payante de monitoring (PM2 Plus) — utile parfois, jamais obligatoire pour les fonctions décrites ici, qui sont toutes gratuites.

✏️ Exercices

Exercice 1 — PM2 ne remonte pas au reboot. Un dev a lancé son app avec pm2 start, tout marche. Après un reboot du VPS, PM2 tourne mais aucune app n’est là. Qu’a-t-il oublié ?

✅ Solution

Deux gestes sont nécessaires et il en manque au moins un. pm2 startup installe le service systemd qui relance le démon PM2 au boot — visiblement fait, puisque PM2 tourne. Mais il a oublié pm2 save, qui fige la liste des process à restaurer. Sans pm2 save, PM2 remonte vide. Correctif : relancer l’app puis pm2 save. Règle : tout changement de liste d’apps → pm2 save.

Exercice 2 — systemd ou PM2 ? Pour chacun de ces cas, recommande systemd ou PM2, avec une raison : (a) une seule app Next.js SSR sur un petit VPS ; (b) six micro-services Node sur une grosse machine, avec besoin de saturer 8 cœurs.

✅ Solution

(a) systemd. Une seule app : pas besoin d’ajouter un outil. systemd est déjà là, gère aussi Nginx et la base, et c’est un seul système à opérer. Sobre et suffisant. (b) PM2. Six apps Node à surveiller : le tableau de bord pm2 monit et l’ergonomie multi-apps deviennent un vrai gain ; et le cluster mode (-i max) exploite les 8 cœurs en une option, là où systemd demanderait un montage manuel. C’est exactement le cas où PM2 brille.

🧠 Quiz de révision

1. PM2 remplace-t-il complètement systemd ?

Non. Pour survivre au reboot, le démon PM2 doit lui-même être relancé — et pm2 startup génère un service systemd pour ça. PM2 est une couche d’ergonomie Node au-dessus de systemd, pas un remplaçant. Même en PM2, systemd est là-dessous.

2. À quoi servent pm2 startup et pm2 save ?

pm2 startup installe le service systemd qui relancera le démon PM2 au boot. pm2 save fige la liste des process actuels pour que PM2 les restaure au démarrage. Les deux sont nécessaires : sans pm2 save, PM2 remonte au boot sans aucune app.

3. Qu’apporte le mode cluster de PM2, et à quelle condition ?

Node est mono-thread (un process = un cœur). Le cluster (-i max) lance plusieurs instances derrière un load balancer interne, une par cœur, en une option — ça exploite tout le CPU. Condition : l’app doit être stateless (pas d’état en RAM partagé entre requêtes), sinon les instances divergent.

4. Quelle est la recommandation par défaut du cours, et quand préférer PM2 ?

systemd par défaut : déjà installé, standard, gère tous les services de la même façon, un seul système à connaître — suffisant pour une app. PM2 quand on gère beaucoup d’apps Node (son dashboard et son ergonomie paient) ou qu’on veut le cluster et le reload sans coupure clé en main.

5. Que se passe-t-il si la même app tourne sous systemd ET PM2 ?

Les deux tentent de la démarrer et se disputent le port (EADDRINUSE), provoquant des redémarrages en boucle. Il faut en choisir un seul et désactiver l’autre (pm2 delete ou systemctl disable --now) avant d’activer le nouveau.


Chapitre suivant : Nginx devant Next — quel que soit ton gestionnaire de process, il faut une façade : le server block Nginx complet pour Next.js.

Last updated on