Node.js : mise en production avec systemd
Faire tourner une application Node.js comme service système : démarrage automatique, redémarrage en cas d’échec, journaux centralisés. Les exemples utilisent des noms génériques (monapp, /srv/monapp, port 3000). Node.js doit être installé avec NodeSource ou le paquet Ubuntu (voir Installation).
Principes
Section intitulée « Principes »- L’application tourne sous un utilisateur dédié, sans droits d’administration.
- Elle écoute sur
127.0.0.1; un reverse proxy (Caddy) gère HTTPS et l’accès depuis Internet. systemddémarre, surveille et redémarre le processus.- Les logs vont sur la sortie standard et sont lus avec
journalctl.
1. Utilisateur et dossier
Section intitulée « 1. Utilisateur et dossier »sudo useradd --system --create-home --home-dir /srv/monapp --shell /usr/sbin/nologin monappsudo -u monapp mkdir -p /srv/monapp/app2. Déployer le code
Section intitulée « 2. Déployer le code »Copier le projet dans /srv/monapp/app (Git, rsync, archive), puis installer les dépendances de production :
sudo rsync -a --delete --exclude node_modules ./ /srv/monapp/app/sudo chown -R monapp:monapp /srv/monapp/appcd /srv/monapp/appsudo -u monapp npm ci --omit=dev3. Variables d’environnement
Section intitulée « 3. Variables d’environnement »Fichier lisible uniquement par root (systemd le lit au démarrage) :
sudo tee /etc/monapp.env <<'CONF'NODE_ENV=productionPORT=3000CONFsudo chmod 600 /etc/monapp.envLes identifiants (base de données, clés d’API) se placent dans ce fichier, jamais dans le code ni dans Git.
4. Service systemd
Section intitulée « 4. Service systemd »Trouver le chemin de Node.js :
command -v node # par exemple /usr/bin/nodeCréer /etc/systemd/system/monapp.service :
sudo tee /etc/systemd/system/monapp.service <<'CONF'[Unit]Description=Application Node.js monappAfter=network.target
[Service]Type=simpleUser=monappGroup=monappWorkingDirectory=/srv/monapp/appEnvironmentFile=/etc/monapp.envExecStart=/usr/bin/node src/serveur.jsRestart=on-failureRestartSec=5
# Durcissement de baseNoNewPrivileges=truePrivateTmp=trueProtectSystem=full
[Install]WantedBy=multi-user.targetCONFActiver et démarrer :
sudo systemctl daemon-reloadsudo systemctl enable --now monappsystemctl status monappcurl http://127.0.0.1:3000/sante| Directive | Rôle |
|---|---|
User / Group |
Utilisateur sans droits d’administration |
EnvironmentFile |
Charge les variables d’environnement |
ExecStart |
Commande de démarrage, chemin absolu de node |
Restart=on-failure |
Redémarre si le processus s’arrête avec une erreur |
NoNewPrivileges |
Interdit l’élévation de privilèges |
PrivateTmp |
/tmp privé pour le service |
ProtectSystem=full |
/usr, /boot et /etc en lecture seule pour le service |
5. Journaux
Section intitulée « 5. Journaux »journalctl -u monapp -f # en directjournalctl -u monapp -n 100 --no-pager # 100 dernières lignesjournalctl -u monapp --since "1 hour ago"journalctl -u monapp -p err # erreurs uniquement6. Reverse proxy avec Caddy
Section intitulée « 6. Reverse proxy avec Caddy »app.exemple.com { encode zstd gzip reverse_proxy 127.0.0.1:3000}Voir Installer Caddy sur Ubuntu et exemples de Caddyfile (en-têtes de sécurité, limites, etc.).
7. Arrêt propre
Section intitulée « 7. Arrêt propre »systemd envoie SIGTERM pour arrêter le service. L’application doit terminer les requêtes en cours puis quitter (voir Premiers pas) :
process.on('SIGTERM', () => { serveur.close(() => process.exit(0));});8. Mettre à jour l’application
Section intitulée « 8. Mettre à jour l’application »cd /srv/monapp/appsudo -u monapp git pull # ou nouvelle copie des fichierssudo -u monapp npm ci --omit=devsudo systemctl restart monappsystemctl status monappPrévoir un retour arrière : conserver la version précédente (tag Git ou copie du dossier) pour pouvoir la restaurer rapidement.
9. Limiter les ressources
Section intitulée « 9. Limiter les ressources »sudo systemctl edit monapp[Service]MemoryMax=512MEnvironment=NODE_OPTIONS=--max-old-space-size=384MemoryMax plafonne la mémoire du service ; --max-old-space-size (en Mo) limite le tas JavaScript de Node.js, en restant en dessous du plafond.
Alternative : PM2
Section intitulée « Alternative : PM2 »PM2 est un gestionnaire de processus propre à Node.js (redémarrage, mode cluster, journaux). Sur Ubuntu, systemd fait déjà l’essentiel et évite une dépendance supplémentaire : PM2 se justifie surtout pour le mode cluster ou la gestion de plusieurs applications avec une même interface.
Ubuntu 24.04 et 26.04 : différences à connaître
Section intitulée « Ubuntu 24.04 et 26.04 : différences à connaître »Pour aller plus loin
Section intitulée « Pour aller plus loin »- Documentation systemd :
man systemd.service - Bonnes pratiques : nodejs.org/en/learn