Héberger une application Node.js
Faire tourner une application derrière nginx, la garder en vie avec systemd ou pm2, et la déployer sans coupure.
Une application Node écoute sur un port local — 3000, par convention. On ne l'expose jamais directement : nginx se place devant, gère le HTTPS, sert les fichiers statiques et transmet le reste. Cette séparation vous permet aussi d'héberger plusieurs applications sur la même machine.
Installer Node
Les paquets de la distribution sont souvent en retard de plusieurs versions. Le dépôt NodeSource donne la version que vous voulez.
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt install -y nodejs
node -vGarder l'application en vie
Deux écoles, également valables. systemd est déjà là et ne demande aucune dépendance ; pm2 est plus simple à prendre en main et gère plusieurs applications d'un coup.
Avec systemd — /etc/systemd/system/mon-appli.service
[Unit]
Description=Mon application Node
After=network.target
[Service]
Type=simple
User=appli
WorkingDirectory=/var/www/mon-appli
ExecStart=/usr/bin/node server.js
Restart=always
RestartSec=5
Environment=NODE_ENV=production
Environment=PORT=3000
[Install]
WantedBy=multi-user.targetAvec pm2
sudo npm install -g pm2
pm2 start server.js --name mon-appli
pm2 save
pm2 startup # affiche une commande à copier-coller pour le démarrage autonginx devant
server {
listen 80;
server_name mon-appli.fr;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
}
}Les en-têtes Upgrade ne sont pas décoratifs
Sans les lignes Upgrade et Connection, les WebSockets ne passent pas : le chat, les notifications en direct et le rechargement à chaud cessent de fonctionner, sans message d'erreur clair. C'est le premier endroit à vérifier quand « ça marche en local mais pas en ligne ».
Écouter en local seulement
Votre application ne doit pas être joignable directement depuis Internet, sinon elle contourne nginx, le HTTPS et vos journaux. Faites-la écouter sur 127.0.0.1.
app.listen(3000, '127.0.0.1');Déployer une nouvelle version
cd /var/www/mon-appli
git pull
npm ci --omit=dev
npm run build
sudo systemctl restart mon-appli # ou : pm2 reload mon-applinpm ci, pas npm install
npm ci installe exactement ce que décrit le fichier de verrouillage, sans le modifier. npm install peut mettre à jour des dépendances au passage : votre production se met alors à différer de ce que vous avez testé, et le jour où ça casse, personne ne comprend pourquoi.
pm2 reload remplace les processus un par un, sans coupure visible. systemctl restart coupe une seconde — acceptable dans la plupart des cas, mais à savoir.
Bloqué malgré tout ? Ouvrez un ticket : on répond en français, et on regarde votre machine si besoin.
Ouvrir un ticket