Project Oxygen & Ideo-LabIDEO LAB Dashboard 2026

⚙️ forever – Process Manager simple pour Node.js

Guide complet IDEO-Lab sur le daemon "forever" pour Node.js (Keep-Alive, Logs, CLI).

1.1

Concept : Keep-Alive (Node.js)

Gardien (Watchdog) simple pour scripts Node.js.

forever Node.js Keep-Alive
1.2

vs. node app.js

Le problème (Crash, Terminal fermé).

Production Crash
1.3

vs. PM2 / Supervisor

forever (Simple) vs PM2 (Cluster) vs Supervisor (Général).

PM2 Supervisor
2.1

Installation (npm)

npm install forever -g.

npm Global
2.2

CLI : forever start

Lancer un script en mode "daemon".

forever start
2.3

CLI : forever list

Lister les processus (PID, Uptime, Logfile).

forever list
3.1

CLI : forever stop

Arrêter un script (par index, PID, ou nom).

forever stop
3.2

CLI : forever restart

Redémarrer un script (Hard restart).

forever restart
3.3

CLI : stopall / restartall

Gérer tous les processus monitorés.

forever stopall
4.1

Gestion des Logs (Défaut)

Capture stdout/stderr (~/.forever/[uid].log).

Logs stdout
4.2

CLI : forever logs

Streamer (tail -f) les logs d'un script.

forever logs
4.3

Options : Logs (-l, -o, -e)

Personnaliser les chemins de logs.

-l (logfile) -a (append)
5.1

Mode Watch (-w)

Redémarrer si fichiers modifiés (Dev, style nodemon).

-w (watch) nodemon
5.2

Options (-c, --uid)

-c python (Autre runtime), --uid (Nom).

-c (command) --uid
5.3

Configuration (JSON)

Utiliser un fichier JSON (similaire à ecosystem).

JSON IaC
6.1

API Programmatique

forever-monitor. Utiliser forever dans un script Node.

forever-monitor API
6.2

Limitation : Cluster Mode

Ne gère pas le clustering (Node.js) natif (vs PM2).

Limitation Cluster
6.3

Limitation : Startup (Boot)

Pas de startup auto (vs PM2). (Nécessite crontab).

Limitation Startup
1.1 Concept : Keep-Alive (Node.js)
Qu'est-ce que forever ?

forever est un gestionnaire de processus (Process Manager) en ligne de commande (CLI), simple et léger, conçu pour les scripts Node.js.

C'est un des "ancêtres" des process managers Node.js (avec nodemon). Son objectif principal est de s'assurer qu'un script (ex: un serveur web) reste "vivant" (Keep-Alive) en production.

Fonctionnement (Watchdog)

forever lance votre script (ex: app.js) en tant que processus enfant (child process), et se met en mode "daemon" (arrière-plan).

Il "surveille" (watch) ce processus enfant. Si le processus enfant crashe (se termine avec un code d'erreur non-zéro), forever le redémarre automatiquement.

1.2 Le Problème : node app.js (en Production)

Lancer une application en production avec node app.js & (ou npm start &) est une très mauvaise pratique.

1. Crash (Panne)

Si votre application (node app.js) rencontre une exception non-gérée (Unhandled Exception), le processus s'arrête (crash).

Résultat : Votre site est DOWN jusqu'à ce qu'un admin se connecte et le relance manuellement.

Solution forever : forever start app.js. Le daemon forever détecte le crash et redémarre le processus instantanément (Auto-Remediation).

2. Fermeture du Terminal (SIGHUP)

Si vous lancez node app.js & (background) via SSH, le processus est toujours lié à votre session terminal.

Résultat : Lorsque vous fermez votre terminal SSH, le système envoie un signal SIGHUP (Hangup) à tous les processus de cette session. Votre node app.js est tué.

Solution forever : forever start app.js lance le script en tant que daemon "détaché", qui n'est pas lié à votre session SSH.

(Note : Des outils comme nohup ou screen/tmux résolvent aussi ce problème spécifique, mais sans le redémarrage automatique).

1.3 Comparaison : forever vs. PM2 vs. Supervisor

forever est le "pionnier", mais PM2 et Supervisor sont des solutions plus robustes.

CritèreforeverPM2 (Moderne Node.js)Supervisor (Généraliste)
LangageNode.jsNode.jsPython
Usage PrincipalScripts Node.js simplesApplications Node.js (Prod)Général (Python, Gunicorn, Celery)
Keep-AliveOui (Crash)Oui (Crash)Oui (Crash, Exit codes)
Cluster (LB)Non (Gros inconvénient)Oui (Natif) (-i max)Non (Gère N copies, mais sans LB)
Startup (Boot)Non (Manuel, via Cron/systemd)Oui (pm2 startup)Non (Géré par systemd)
Config (IaC)JSON (Basique)Ecosystem.js (Puissant).conf (INI) (Robuste)
MonitoringCLI (list, logs)CLI (monit), Web (PM2 Plus)CLI (supervisorctl), Web UI
Reload (Zero-Downtime)Non (restart uniquement)Oui (reload)Non (restart uniquement)

Verdict : forever est suffisant pour un petit script simple. Pour toute application Node.js de production (serveur web), PM2 est le standard.

2.1 CLI : forever start [script]

La commande start lance le script en mode "daemon" (arrière-plan).

$ forever start app.js
warn:    --minUptime not set. Defaulting to: 1000ms
warn:    --spinSleepTime not set. Defaulting to: 1000ms
info:    Forever processing file: app.js
info:    Script TOTO added to list.

$ forever list
info:    Forever processes running
data:        uid  command       script  forever pid   id logfile                 uptime
data:    [0] TOTO /usr/bin/node app.js  23456   23458    /home/user/.forever/TOTO.log 1s
  • uid : L'ID (nom) unique du processus (ici, TOTO, généré aléatoirement si --uid n'est pas défini).
  • command : Le runtime (ex: node).
  • script : Le script (app.js).
  • forever pid : Le PID du daemon forever (parent).
  • pid : Le PID du processus app.js (enfant).
  • logfile : Le chemin vers le fichier de log (stdout/stderr).
2.2 CLI : forever list

forever list (ou forever ls) est l'équivalent de pm2 list ou supervisorctl status.

$ forever list
info:    Forever processes running
data:        uid  command       script    forever pid   id logfile                     uptime
data:    [0] api  /usr/bin/node api.js    23456   23458    /home/user/.forever/api.log   2d 5h 10m
data:    [1] bot  /usr/bin/node bot.js    23500   23502    /home/user/.forever/bot.log   1h 20m
data:    [2] old  /usr/bin/node old.js    0       0        /home/user/.forever/old.log   STOPPED

Analyse :

  • [0] api : (ID 0, uid api) Tourne depuis 2 jours.
  • [1] bot : (ID 1, uid bot) Tourne depuis 1h 20m.
  • [2] old : (ID 2, uid old) Est STOPPED. (PID = 0).
3.1 CLI : forever stop

forever stop arrête un processus (il reste dans la liste avec le statut STOPPED).

Méthodes d'identification

Vous pouvez stopper un processus de 4 manières :

# 1. Par l'Index (recommandé)
$ forever stop 0   (Arrête l'ID [0] de 'forever list')

# 2. Par le 'uid' (si défini, voir 5.2)
$ forever stop api

# 3. Par le nom du script
$ forever stop app.js

# 4. Par le PID (du 'child' (enfant))
$ forever stop 23458
3.2 CLI : forever restart

forever restart est un "hard restart" (Stop + Start). Il ne fait pas de "Zero-Downtime reload" (comme PM2).

# Redémarre l'ID [0]
$ forever restart 0
info:    Stopping process: api
info:    Process api stopped
info:    Forever processing file: api.js
info:    Script api added to list.

# (Le PID va changer)
3.3 CLI : stopall & restartall
stopall

Arrête tous les processus RUNNING gérés par forever.

$ forever stopall
info:    Stopping all running processes
info:    Process api stopped
info:    Process bot stopped
restartall

Redémarre tous les processus RUNNING.

4.1 Gestion des Logs (stdout/stderr)

forever (comme supervisor) capture stdout (console.log) et stderr (console.error, exceptions) des processus enfants.

Emplacement par Défaut

Par défaut, il crée un fichier de log unique (qui combine stdout/stderr) dans ~/.forever/.

$ forever list
data:        uid  ...  logfile
data:    [0] api  ...  /home/ideo/.forever/api.log

Rotation : forever ne gère pas la rotation des logs (logrotate) nativement. Les fichiers .log peuvent devenir énormes.

4.2 CLI : forever logs (Streaming)

La commande forever logs est l'équivalent de pm2 logs ou tail -f. Elle "stream" (affiche en temps réel) les logs.

# Streamer les logs d'un script (par index)
$ forever logs 0

# Streamer (tail) les logs (force -f)
$ forever logs 0 -f

# Streamer (par nom de script)
$ forever logs api.js

# Afficher les 100 dernières lignes (pas de stream)
$ forever logs 0 -n 100
4.3 Options : Personnalisation des Logs

Vous pouvez (devez) personnaliser les chemins de logs au lieu d'utiliser ~/.forever/.

OptionDescription
-l [CHEMIN](Logfile) Log stdout ET stderr dans ce fichier (combiné).
-o [CHEMIN](Out file) Log stdout (uniquement) dans ce fichier.
-e [CHEMIN](Error file) Log stderr (uniquement) dans ce fichier.
-a (ou --append)(Important) "Append" (Ajouter) aux logs. Si omis, forever restart écrase (overwrite) le fichier log.
Exemple (Production)
# (Lance api.js)
# (Ajoute les logs 'stdout' à api-out.log)
# (Ajoute les logs 'stderr' à api-err.log)
$ forever start -a -o /var/log/myapp/api-out.log \
                -e /var/log/myapp/api-err.log \
                app.js
5.1 Mode Watch (-w) (Développement)

L'option -w (ou --watch) est l'équivalent de nodemon.

forever va "surveiller" (watch) le dossier (watchDirectory) du script. Si un fichier (ex: app.js) est modifié (sauvegardé), forever redémarre (restart) automatiquement le processus.

# 1. Démarrer en mode "watch"
$ forever start -w app.js

# 2. (Modifier et sauvegarder app.js)
# (forever détecte le changement)
info:    Changes detected in /path/to/app.js. Restarting...
info:    Process app.js stopped
info:    Forever processing file: app.js
...

Attention : Ne jamais utiliser --watch en Production (sauf cas très spécifique). C'est un outil de Développement.

5.2 Options (-c, --uid)
OptionDescriptionExemple
--uid [nom]Définit un nom (uid) personnalisé pour le processus (au lieu d'un nom aléatoire comme "TOTO").forever start app.js --uid "api"
-c [cmd](Command) Spécifie le runtime à utiliser. (Défaut : node).forever start -c python script.py
--pidFile [path]Stocke le PID du daemon forever (parent) dans un fichier.--pidFile /var/run/forever.pid
--max [n]Nombre maximum de redémarrages (défaut : 10).--max 5
--minUptime [ms]Temps (ms) qu'un script doit tourner pour être "stable".--minUptime 5000 (5 sec)
5.3 Configuration (JSON)

forever (comme PM2) peut être lancé avec un fichier de configuration (JSON) pour définir les options (IaC).

Fichier (config.json)
[
  {
    // (Process 1)
    "uid": "api-web",
    "script": "app.js",
    "watch": false,
    "logFile": "/var/log/myapp/api.log",
    "append": true,
    "max": 10,
    "minUptime": 5000
  },
  {
    // (Process 2)
    "uid": "worker",
    "script": "worker.js",
    "logFile": "/var/log/myapp/worker.log",
    "append": true
  }
]
Lancement (CLI)
# Démarrer TOUS les scripts du JSON
$ forever start config.json

# Stopper TOUS les scripts du JSON
$ forever stop config.json
6.1 API Programmatique (forever-monitor)

forever peut être utilisé comme une bibliothèque (library) Node.js (forever-monitor) pour gérer des processus enfants depuis votre propre code.

const forever = require('forever-monitor');

// 1. Définir l'enfant (child)
const child = new (forever.Monitor)('mon_script_enfant.js', {
    max: 3,
    silent: false,
    args: ['--port=8080']
});

// 2. Événements (Events)
child.on('watch:restart', (info) => {
    console.log('Restarting script because ' + info.file + ' changed');
});

child.on('restart', () => {
    console.log('Forever restarting script for ' + child.times + ' time');
});

child.on('exit:code', (code) => {
    console.log('Script exited with code ' + code);
});

// 3. Démarrer
child.start();
6.2 Limitation : Pas de Mode Cluster

C'est la limitation majeure de forever par rapport à PM2.

forever ne supporte pas le "Clustering" (Load Balancing) natif. Il n'a pas d'équivalent au pm2 start -i max.

Le Problème (Node.js Mono-Thread)

Si vous lancez forever start app.js sur un serveur à 16 Cœurs, votre application ne tournera que sur 1 Cœur, laissant 15 Cœurs (94% du serveur) inutilisés.

Contournement (Manuel)

Le seul moyen de contourner (maladroitement) est de lancer 16 copies manuelles (ou via JSON) sur 16 ports différents (8001, 8002...) et de mettre un Load Balancer (Nginx, HAProxy) en façade.

Conclusion : forever est obsolète pour les serveurs web Node.js. PM2 (2.3) gère cela nativement (via le module cluster de Node.js).

6.3 Limitation : Pas de "Startup" (Boot)

forever ne fournit pas d'utilitaire (comme pm2 startup) pour créer automatiquement un service de démarrage (systemd ou init.d).

Le Problème

Si vous lancez forever start app.js et que le serveur (VM) redémarre, vos applications sont DOWN. Le daemon forever lui-même n'a pas été relancé.

Solution (Manuelle)

Vous devez manuellement créer un service systemd (ou un crontab @reboot) pour lancer forever au démarrage.

Exemple (Crontab @reboot)
# (Exécuter 'crontab -e' pour l'utilisateur 'ideo')

# (Au redémarrage, lancer 'forever' pour
#  démarrer TOUS les scripts sauvegardés)
@reboot /usr/bin/forever startall
Exemple (systemd)

Créer un /etc/systemd/system/forever.service (Complexe).