Skip to content
VDS · Sites web et serveurs web

Une application Node.js sous systemd

Comment exécuter une application Node sur VDS pour qu'elle survive à une déconnexion SSH et à un redémarrage de la machine : unité systemd, variables d'environnement, journaux.

Mis à jour le 23 août 2026

Un node index.js lancé manuellement s'arrête avec la session SSH. Pour maintenir l'application en fonctionnement permanent et la faire redémarrer après un redémarrage, exécutez-la en tant que service systemd — c'est un mécanisme système intégré, il n'y a donc rien à installer.

Préparation

Installez Node depuis le dépôt officiel, et non depuis l'ancien paquet système :

curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
apt install -y nodejs
node -v

Créez un utilisateur dédié — l'application ne doit pas s'exécuter en tant que root :

useradd -r -m -d /srv/app -s /usr/sbin/nologin appuser
chown -R appuser:appuser /srv/app
sudo -u appuser npm ci --omit=dev --prefix /srv/app

Service systemd

Le fichier /etc/systemd/system/myapp.service :

[Unit]
Description=My Node app
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=appuser
WorkingDirectory=/srv/app
EnvironmentFile=/srv/app/.env
ExecStart=/usr/bin/node /srv/app/index.js
Restart=always
RestartSec=5
NoNewPrivileges=true
PrivateTmp=true

[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable --now myapp
systemctl status myapp

Restart=always relance le processus après un plantage. EnvironmentFile est un simple fichier KEY=value sans guillemets ni export ; définissez ses permissions sur 600, car il contient des mots de passe.

Exposition via un proxy

L'application doit écouter uniquement sur 127.0.0.1:3000, et un serveur web muni d'un certificat la sert vers l'extérieur :

location / {
    proxy_pass http://127.0.0.1:3000;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

Pour plus de détails, consultez reverse proxy et Let's Encrypt. Si l'application écoute sur 0.0.0.0, elle est joignable depuis internet en contournant le proxy et sans chiffrement.

Journaux et mises à jour

journalctl -u myapp -f
journalctl -u myapp --since "1 hour ago" -p err
systemctl restart myapp

La sortie vers stdout est transmise automatiquement au journal — vous n'avez pas besoin de configurer vos propres fichiers de journal ni de rotation des journaux.

Erreurs courantes

SymptômeCause
status=203/EXECChemin incorrect vers node ou vers le fichier dans ExecStart — utilisez des chemins absolus
Le service redémarre en boucleL'application plante au démarrage : vérifiez journalctl -u myapp -n 50
EADDRINUSEUn processus lancé manuellement tourne encore : ss -tulpn | grep 3000
Fonctionne en SSH, mais pas en tant que serviceLes variables d'environnement sont absentes — systemd ne les a pas, définissez-les dans EnvironmentFile
La compilation manque de mémoire sur VDS-1Compilez localement et téléversez la compilation terminée sur la machine

Ne placez pas pm2 au-dessus de systemd. Deux superviseurs sur un même processus créent de la confusion : systemd considère le processus comme actif tandis que pm2 le redémarre.