
Le guide de Nginx montre comment relayer une requête vers un autre service. Appliquons ce principe à une application Node.js : elle écoute localement, tandis que systemd gère son démarrage et ses journaux.
1. Préparer un processus autonome
Il vous faut un VPS Ubuntu, sudo, Nginx et une version de Node.js encore prise en charge, compatible avec votre projet. Vérifiez node --version et command -v node : adaptez ensuite le chemin absolu de l'unité. L'exemple utilise /usr/bin/node.
sudo useradd --system --home-dir /srv/nodeapp \ --shell /usr/sbin/nologin nodeappsudo install -d -o root -g nodeapp -m 750 /srv/nodeappsudoedit /srv/nodeapp/server.jsCe petit serveur sans dépendances permet de valider le déploiement :
const http = require('node:http');const server = http.createServer((req, res) => { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('nodeapp ready\n');});server.listen( Number(process.env.PORT || 3000), process.env.HOST || '127.0.0.1');process.on('SIGTERM', () => server.close());Pour votre projet, remplacez ce fichier par l'artefact testé et ses dépendances de production ; construisez-le avant de lancer le service. Gardez le code lisible mais non modifiable par nodeapp. Prévoyez un dossier séparé, détenu par ce compte, si l'application doit écrire des données.
2. Confier l'exécution à systemd
Créez la configuration, puis éditez-la :
sudo install -m 600 /dev/null /etc/nodeapp.envsudoedit /etc/nodeapp.envNODE_ENV=productionHOST=127.0.0.1PORT=3000Aucun export ni script shell : ces lignes sont des valeurs. L'application doit les lire ; déclarer HOST seul ne change pas une application qui l'ignore. Évitez de journaliser des secrets.
Dans /etc/systemd/system/nodeapp.service, avec sudoedit :
[Unit]Description=Node applicationAfter=network.target [Service]Type=simpleUser=nodeappGroup=nodeappWorkingDirectory=/srv/nodeappEnvironmentFile=/etc/nodeapp.envExecStart=/usr/bin/node /srv/nodeapp/server.jsRestart=on-failureRestartSec=5NoNewPrivileges=truePrivateTmp=trueStandardOutput=journalStandardError=journal [Install]WantedBy=multi-user.targetsudo systemctl daemon-reloadsudo systemctl enable --now nodeappcurl -fsS http://127.0.0.1:3000/sudo journalctl -u nodeapp -n 30 --no-pagerAprès une modification du fichier d'environnement, redémarrez le service. Après une modification de l'unité, faites aussi daemon-reload.
3. Relayer puis tester la récupération
Dans le bloc server Nginx de votre domaine, remplacez son location / par ceci. Conservez sa configuration HTTPS existante ; pour un site neuf, configurez son domaine et son certificat avant d'y faire passer des identifiants.
location / { proxy_pass http://127.0.0.1:3000; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Proto $scheme;}Ce modèle suppose Nginx directement exposé aux visiteurs et du HTTP classique. Un CDN en amont ou WebSocket demande une configuration adaptée. Ne publiez pas le port 3000.
sudo nginx -t && sudo systemctl reload nginxcurl -fsS https://example.com/sudo systemctl kill --kill-whom=main \ --signal=SIGKILL nodeappsleep 6systemctl is-active nodeappcurl -fsS http://127.0.0.1:3000/Remplacez le domaine et faites ce test d'arrêt seulement avant ouverture au trafic. Attendez active et la réponse attendue, puis vérifiez le site après un redémarrage planifié du VPS.
Erreurs courantes : 203/EXEC indique notamment un mauvais chemin Node ; EADDRINUSE signale un port occupé ; un 502 nécessite de tester d'abord l'écoute locale. systemctl stop ne déclenche pas la récupération automatique : c'est un arrêt demandé.