Chapitre 9.3 — PM2, l’alternative
⏱️ TL;DR — PM2 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.jsversionné, le mode cluster (plusieurs instances sur tes cœurs, en une option), du monitoring intégré (pm2 monit), et unpm2 reloadsans coupure. Point crucial : pour survivre au reboot, PM2 s’appuie quand même sur systemd (pm2 startupgé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 directpm2 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.jsdans le repo, mais jamais les secrets dedans. Mets-y le non-secret (NODE_ENV,PORT) et charge les secrets depuis un.envhors git (PM2 sait lire un fichier d’env, ou ton app le charge elle-même). Unecosystem.config.jsavec un mot de passe de base committé, c’est la même fuite que le piègeNEXT_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 bootRetiens 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 startupinstalle le service, mais c’estpm2 savequi fige la liste des process à restaurer. Sans lui, PM2 remonte au boot… sans aucune app. Et si tu ajoutes une app plus tard sans refairepm2 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 CPULe 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ère | systemd | PM2 |
|---|---|---|
| Déjà installé | Oui (natif Linux) | Non (npm i -g pm2) |
| Portée | Tous les services (Node, Postgres, Nginx…) | Node uniquement |
| Survie au boot | Native (enable) | Via systemd (pm2 startup) |
| Survie au crash | Restart=always | Native |
| Cluster multi-cœurs | Manuel (plusieurs units / socket) | Une option (-i max) |
| Reload sans coupure | Dépend de l’app | Natif (pm2 reload) |
| Monitoring intégré | systemctl/journalctl (sobre) | pm2 monit, dashboard (riche) |
| Config | unit .service dans /etc | ecosystem.config.js dans le repo |
| Courbe d’apprentissage | À connaître de toute façon | Une couche de plus |
| Un seul système à maîtriser | Oui | Non (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(ousystemctl 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 lorsquepm2 startupte 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 ; sousdeploy, 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-apiet 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 bordpm2 monitdeviendraient 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, ledeployinté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 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.