
En cours d’exécution node app.js sur un ordinateur portable de développeur, c’est une chose ; obtenir le même code pour rester actif sur un serveur de production, redémarrer après un crash, survivre à un redémarrage et répondre aux demandes sur les ports HTTPS standard en est une autre. Un déploiement Node.js fonctionnel sur Ubuntu 26.04 comporte trois parties mobiles : le runtime, un gestionnaire de processus qui maintient l’application en vie et un proxy inverse qui gère TLS et achemine le trafic vers l’application.
Ce guide explique comment déployer une application Node.js sur Ubuntu 26.04 en utilisant PM2 comme gestionnaire de processus et Nginx comme proxy inverse, avec un certificat Let’s Encrypt devant.
Conditions préalables
Avant de commencer il vous faut :
- Ubuntu 26.04 avec un utilisateur qui a
sudoprivilèges - Un nom de domaine avec un enregistrement A pointant vers l’IP publique du serveur
- Ports 80 et 443 ouverts dans le pare-feu
Nous utiliserons example.com et une application qui écoute sur le port 3000. Remplacez vos vraies valeurs.
Étape 1 : Installer Node.js
Ubuntu 26.04 inclut Node.js dans ses référentiels, mais NodeSource facilite l’installation d’une version LTS en amont spécifique. Les commandes ci-dessous installent Node.js 24.x, la ligne LTS actuelle au moment de la publication.
Installez les packages requis et importez la clé de signature NodeSource :
Terminal
sudo apt update
sudo apt install -y ca-certificates curl gnupg
sudo mkdir -p /etc/apt/keyrings
curl -fsSL | \
sudo gpg --dearmor --yes -o /etc/apt/keyrings/nodesource.gpg
Ajoutez le dépôt Node.js 24.x :
Terminal
NODE_MAJOR=24
echo "deb (signed-by=/etc/apt/keyrings/nodesource.gpg) https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | \
sudo tee /etc/apt/sources.list.d/nodesource.list
Mettez à jour l’index du package et installez Node.js :
Terminal
sudo apt update
sudo apt install -y nodejs
Confirmez que les deux binaires sont en place :
Terminal
node --version
npm --version
sortir
v24.16.0
11.16.0
Les versions exactes des correctifs changeront à mesure que les mises à jour de Node.js et npm seront publiées. Pour d’autres méthodes d’installation, consultez notre guide sur l’installation de Node.js et npm sur Ubuntu 26.04.
Étape 2 : préparer un utilisateur et un répertoire de déploiement
Les applications de production doivent s’exécuter en tant que compte non root possédant uniquement ses propres fichiers. Créez un utilisateur dédié :
Terminal
sudo adduser --system --group --home /var/www/app --shell /bin/bash app
Le --system flag crée un compte avec la connexion par mot de passe désactivée, ce qui est approprié pour un compte de service. Les administrateurs peuvent toujours exécuter des commandes de déploiement en tant qu’utilisateur via sudo.
Configurez le répertoire de déploiement :
Terminal
sudo mkdir -p /var/www/app
sudo chown -R app:app /var/www/app
Étape 3 : Installez l’application sur le serveur
La plupart des déploiements extraient le code de Git. Clonez le référentiel en tant que app utilisateur:
Terminal
sudo apt install -y git
sudo -H -u app git clone /var/www/app
Installez les dépendances dans ce répertoire :
Terminal
sudo -H -u app bash -c 'cd /var/www/app && npm ci --omit=dev'
npm ci est la bonne commande pour les déploiements : elle lit package-lock.json et refuse de reculer lorsque le fichier de verrouillage est désynchronisé. --omit=dev ignore les dépendances de développement uniquement, ce qui réduit la taille de l’installation de production.
Si l’application comporte une étape de génération qui dépend des packages de développement, installez d’abord toutes les dépendances, créez le projet, puis supprimez les packages de développement uniquement :
Terminal
sudo -H -u app bash -c \
'cd /var/www/app && npm ci && npm run build && npm prune --omit=dev'
Pour les référentiels privés, configurez une clé de déploiement SSH ou un jeton d’accès de courte durée pour le app compte. Ne stockez pas les informations d’identification du référentiel dans le répertoire de l’application.
Pour un test rapide sans véritable référentiel, écrivez plutôt une application Express minimale :
Terminal
sudo -H -u app bash -c 'cd /var/www/app && npm init -y && npm install express'
sudo -H -u app nano /var/www/app/server.js
/var/www/app/server.jsjs
const express = require("express");
const app = express();
const port = 3000;
app.get("/", (req, res) => {
res.send("Hello from Node.js on Ubuntu 26.04");
});
app.listen(port, "127.0.0.1", () => {
console.log(`App listening on http://127.0.0.1:${port}`);
});
Notez que l’appel d’écoute se lie à 127.0.0.1pas 0.0.0.0. Le proxy inverse atteindra l’application via un bouclage, et la liaison à localhost maintient entièrement l’application hors du réseau public.
Étape 4 : Installez PM2 et exécutez l’application
PM2 est un gestionnaire de processus Node.js qui gère les redémarrages, les journaux et le clustering. Installez-le globalement :
Terminal
sudo npm install -g pm2
Configurez toutes les variables d’environnement requises avant de démarrer le processus. Conservez les clés API, les mots de passe de base de données et autres secrets en dehors du référentiel Git et ajoutez des .env fichiers à .gitignore.
Démarrez l’application sous PM2 comme app utilisateur:
Terminal
sudo -H -u app pm2 start /var/www/app/server.js --name myapp --time
sortir
(PM2) Starting /var/www/app/server.js in fork_mode (1 instance)
(PM2) Done.
┌─────┬────────┬─────────────┬─────────┬─────────┬──────────┬────────┐
│ id │ name │ namespace │ version │ mode │ pid │ uptime │
├─────┼────────┼─────────────┼─────────┼─────────┼──────────┼────────┤
│ 0 │ myapp │ default │ 1.0.0 │ fork │ 12345 │ 0s │
└─────┴────────┴─────────────┴─────────┴─────────┴──────────┴────────┘
Vérifiez que l’application répond lors du bouclage :
Terminal
curl
sortir
Hello from Node.js on Ubuntu 26.04
Pour que PM2 démarre l’application au démarrage, générez l’unité systemd et figez la liste des processus :
Terminal
sudo env PATH=$PATH:/usr/bin pm2 startup systemd -u app --hp /var/www/app
sudo -H -u app pm2 save
La première commande écrit et active pm2-app.service; le second enregistre la liste des processus en cours afin que PM2 sache par où commencer. Confirmez que l’unité est activée :
Terminal
sudo systemctl status pm2-app
Étape 5 : Installer et configurer Nginx
Installez Nginx :
Terminal
sudo apt install nginx
Créez un bloc serveur qui transmet les requêtes à l’application Node.js :
Terminal
sudo nano /etc/nginx/sites-available/example.com
/etc/nginx/sites-available/example.comnginx
server {
listen 80;
listen (::):80;
server_name example.com www.example.com;
location / {
proxy_pass ;
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;
}
}
Les en-têtes conservent l’hôte d’origine, l’adresse IP du client et le protocole de l’application. Si l’application utilise WebSockets, ajoutez les paramètres de mise à niveau du guide du proxy inverse Nginx.
Activez le site et testez la configuration :
Terminal
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
Ouvrez le pare-feu :
Terminal
sudo ufw allow 'Nginx Full'
Visite et confirmez le rendu de la page. Les requêtes transitent désormais du navigateur vers Nginx sur le port 80, puis vers Node.js sur le port de bouclage 3000.
Étape 6 : ajouter HTTPS avec Certbot
Installez Certbot et le plugin Nginx :
Terminal
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com
Certbot réécrit le bloc serveur pour mettre fin à TLS, ajoute une redirection HTTP vers HTTPS et enregistre un minuteur de renouvellement. Vérifier:
Terminal
curl -I
sudo certbot renew --dry-run
La première commande doit renvoyer un statut HTTP réussi sur HTTPS. L’essai de renouvellement confirme que Certbot peut renouveler le certificat avant son expiration.
Étape 7 : Gérer l’application avec PM2
Une fois le déploiement opérationnel, les opérations quotidiennes passent toutes par PM2 :
Terminal
sudo -H -u app pm2 ls
sudo -H -u app pm2 logs myapp
sudo -H -u app pm2 restart myapp
sudo -H -u app pm2 stop myapp
PM2 écrit la sortie de l’application sous /var/www/app/.pm2/logs. Installez le module de rotation des journaux pour que ces fichiers ne grossissent pas sans limite :
Terminal
sudo -H -u app pm2 install pm2-logrotate
sudo -H -u app pm2 set pm2-logrotate:max_size 10M
sudo -H -u app pm2 set pm2-logrotate:retain 7
Pour déployer une nouvelle version, effectuez uniquement les modifications rapides, installez les dépendances et redémarrez le processus :
Terminal
sudo -H -u app bash -c \
'cd /var/www/app && git pull --ff-only && npm ci --omit=dev'
sudo -H -u app pm2 restart myapp --update-env
sudo -H -u app pm2 save
Ce guide démarre l’application en mode fork, donc pm2 restart interrompt brièvement les demandes. Aucun temps d’arrêt pm2 reload nécessite le mode cluster avec au moins deux instances :
Terminal
sudo -H -u app pm2 delete myapp
sudo -H -u app pm2 start /var/www/app/server.js --name myapp -i 2 --time
sudo -H -u app pm2 save
sudo -H -u app pm2 reload myapp
Le mode cluster fonctionne bien pour les applications HTTP sans état. Les applications qui conservent les sessions, les tâches planifiées ou l’état de WebSocket en mémoire nécessitent un magasin externe ou une coordination supplémentaire avant d’exécuter plusieurs instances.
Dépannage
502 Bad Gateway de Nginx
L’application Node.js n’est pas en cours d’exécution, n’écoute pas sur le port attendu ou est liée à la mauvaise adresse. Vérifier sudo -H -u app pm2 ls et confirmez que le processus est en ligne, puis exécutez sudo ss -ltnp | grep 3000 pour confirmer qu’il écoute en boucle.
PM2 ne démarre pas au démarrage
L’unité systemd n’était pas activée, ou pm2 save a été ignoré. Vérifier sudo systemctl status pm2-appréexécutez la commande de démarrage, puis exécutez sudo -H -u app pm2 save.
Certbot ne peut pas valider le domaine
Confirmez que les enregistrements A et AAAA du domaine pointent vers ce serveur, que le port 80 est accessible et sudo ufw status montre Nginx Full autorisé. Si un enregistrement AAAA incorrect pointe ailleurs, la validation Let’s Encrypt peut échouer même lorsque l’enregistrement A est correct.
FAQ
Pourquoi utiliser Nginx devant Node.js ?
Nginx gère les ports publics et le certificat TLS tandis que le processus Node.js reste sur un port local non privilégié. Il vous offre également un emplacement unique pour les limites de requêtes, les fichiers statiques, les journaux d’accès et le routage de plusieurs applications par domaine.
Puis-je exécuter plusieurs applications Node.js sur le même serveur ?
Oui. Donnez à chaque application son propre port, sa propre entrée PM2 et son propre bloc de serveur Nginx. Le proxy inverse achemine par nom d’hôte afin que chaque application reçoive les requêtes pour son domaine uniquement.
Dois-je utiliser PM2 ou systemd directement ?
Les deux fonctionnent. PM2 ajoute des contrôles de processus, un clustering et des rechargements spécifiques à Node.js, tandis que systemd est plus simple lorsque vous n’avez besoin de superviser qu’un seul processus. Dans cette configuration, systemd démarre PM2 au démarrage et PM2 gère l’application.
Conclusion
Un déploiement de production Node.js sur Ubuntu 26.04 utilise PM2 pour maintenir l’application en cours d’exécution et Nginx pour gérer le trafic public HTTP et HTTPS. Gardez l’application liée au bouclage, faites pivoter ses journaux et testez la procédure de mise à jour avant que le serveur ne transporte le trafic de production.
Pour une configuration associée, consultez nos guides sur l’installation de Node.js sur Ubuntu 26.04 et la configuration de Nginx en tant que proxy inverse.