Cas d'usage : petite application de questionnaires (trafic léger)
IIS reste le serveur web exposé publiquement (port 80/443) et agit comme reverse proxy vers l'application Node.js, qui tourne en arrière-plan comme service Windows (géré par NSSM) sur un port local. C'est l'approche à privilégier aujourd'hui pour un déploiement durable.
Ce document décrit, pas à pas, comment déployer une application Node.js sur un Windows Server existant, en utilisant IIS comme point d'entrée public. Il est pensé pour une application à faible trafic (formulaires / réponses à des questionnaires), mais les étapes restent valables pour la plupart des applications Node.js classiques (Express, Fastify, etc.).
IIS n'exécute pas directement le code Node — il transmet les requêtes à l'application Node via un reverse proxy. L'application, elle, tourne en permanence en arrière-plan sur un port local (ex. 3000), démarrée et surveillée par NSSM en tant que service Windows.
Schéma : Internet → IIS (port 443, certificat SSL) → module URL Rewrite + ARR → Node.js (127.0.0.1:3000, exécuté par NSSM en tant que service Windows).
Si IIS n'est pas encore installé sur le serveur :
# PowerShell, en tant qu'administrateur Install-WindowsFeature -Name Web-Server -IncludeManagementTools
Ou via l'interface graphique : Gestionnaire de serveur → Ajouter des rôles et fonctionnalités → Serveur Web (IIS) → cocher au minimum : Contenu statique, Document par défaut, Journalisation HTTP, Filtrage des requêtes, Console de gestion IIS.
node -v npm -v
Les deux commandes doivent afficher un numéro de version sans erreur.
Indispensable pour rediriger les requêtes entrantes vers l'application Node. Télécharger et installer « URL Rewrite Module 2.1 » depuis le site officiel IIS (iis.net/downloads/microsoft/url-rewrite).
Nécessaire pour que IIS agisse comme reverse proxy vers un port local. Télécharger et installer « Application Request Routing 3.0 » depuis le même site (iis.net/downloads/microsoft/application-request-routing).
Après installation d'ARR, ouvrir IIS Manager → sélectionner le nœud du serveur (racine) → double-cliquer sur « Application Request Routing Cache » → dans le panneau Actions à droite, cliquer sur « Server Proxy Settings » → cocher « Enable proxy » → Appliquer.
Redémarrage : un redémarrage du service IIS (ou du serveur) est recommandé après l'installation des deux modules :iisreseten ligne de commande administrateur.
cd D:\Apps\questionnaire-app npm ci --omit=dev
// server.js const PORT = process.env.PORT || 3000; app.listen(PORT, "127.0.0.1", () => { console.log(`App started on 127.0.0.1:${PORT}`); });
node server.js # puis, dans un autre terminal : curl http://127.0.0.1:3000
Sans cette étape, l'application s'arrête dès que la session qui l'a lancée se ferme, et ne redémarre pas après un reboot du serveur. NSSM (Non-Sucking Service Manager) résout ce problème simplement.
cd C:\Tools\nssm nssm install QuestionnaireApp
Une fenêtre NSSM s'ouvre. Renseigner :
Dans l'onglet « I/O », rediriger la sortie standard et les erreurs vers des fichiers de log (ex. D:\Apps\questionnaire-app\logs\out.log et err.log) pour faciliter le diagnostic.
Dans l'onglet « Exit actions », choisir « Restart application » en cas d'arrêt inattendu.
Démarrer et vérifier le service :
nssm start QuestionnaireApp Get-Service QuestionnaireApp curl http://127.0.0.1:3000
Créer un fichier web.config à la racine du dossier qui sera utilisé comme racine du site IIS (peut être un dossier vide dédié, distinct du code Node, ex. D:\Sites\questionnaire\) :
<?xml version="1.0" encoding="UTF-8"?> <configuration> <system.webServer> <rewrite> <rules> <rule name="ReverseProxyToNode" stopProcessing="true"> <match url="(.*)" /> <action type="Rewrite" url="http://127.0.0.1:3000/{R:1}" /> </rule> </rules> </rewrite> </system.webServer> </configuration>
Ce fichier indique à IIS (via URL Rewrite + ARR) de transmettre toutes les requêtes reçues vers l'application Node en écoute sur le port local 3000.
Fortement recommandé dès que le questionnaire transmet des données, même peu sensibles.
<rule name="ForceHTTPS" stopProcessing="true"> <match url="(.*)" /> <conditions> <add input="{HTTPS}" pattern="off" /> </conditions> <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" /> </rule>
Cette règle doit être placée avant la règle ReverseProxyToNode dans le web.config.
Autoriser uniquement les ports nécessaires en entrée : 80 et 443 pour IIS. Le port 3000 (Node) ne doit pas être ouvert à l'extérieur — il ne doit rester accessible qu'en local puisque Node écoute sur 127.0.0.1.
New-NetFirewallRule -DisplayName "IIS HTTP" -Direction Inbound -Protocol TCP -LocalPort 80 -Action Allow New-NetFirewallRule -DisplayName "IIS HTTPS" -Direction Inbound -Protocol TCP -LocalPort 443 -Action Allow
curl http://127.0.0.1:3000 doit répondre (Node direct).curl http://localhost/ doit répondre la même chose (via IIS + reverse proxy).http://nom-du-site puis https://nom-du-site dans un navigateur.Quelques points à vérifier côté code Node, en plus de la configuration IIS/réseau :
npm install helmet) pour les en-têtes de sécurité HTTP par défaut.git pull ou copie de fichiers) dans D:\Apps\questionnaire-app\.npm ci –omit=dev.nssm stop QuestionnaireApp.nssm start QuestionnaireApp.Bonnes pratiques : pour limiter les interruptions, prévoir les mises à jour en dehors des heures d'utilisation du questionnaire, et garder une copie de la version précédente pour pouvoir revenir en arrière rapidement en cas de problème.
| Élément | Statut |
|---|---|
| Rôle IIS installé | ☐ |
| Node.js installé et vérifié (node -v) | ☐ |
| URL Rewrite + ARR installés, proxy activé | ☐ |
| Application copiée, dépendances installées (npm ci) | ☐ |
| Application testée en local sur 127.0.0.1:3000 | ☐ |
| Service NSSM créé, démarré, redémarrage auto configuré | ☐ |
| web.config reverse proxy en place | ☐ |
| Site créé dans IIS, binding http configuré | ☐ |
| Certificat SSL installé, binding https configuré | ☐ |
| Redirection HTTP → HTTPS active | ☐ |
| Pare-feu : ports 80/443 ouverts, 3000 fermé en externe | ☐ |
| Test de bout en bout du questionnaire réussi | ☐ |
| Redémarrage serveur testé (reprise automatique) | ☐ |
| Logs NSSM et IIS vérifiés | ☐ |
| Sécurité applicative revue (helmet, validation, rate limit) | ☐ |
| Symptôme | Piste de résolution |
|---|---|
| Erreur 502.3 (Bad Gateway) dans IIS | Vérifier que le service NSSM tourne (Get-Service QuestionnaireApp) et que curl http://127.0.0.1:3000 répond en local. |
| Erreur 500.19 sur le site IIS | web.config invalide ou module URL Rewrite/ARR non installé — vérifier la syntaxe XML et la présence des modules. |
| Le site répond en HTTP mais pas en HTTPS | Vérifier le binding 443 et que le certificat sélectionné est valide et non expiré. |
| L'application ne redémarre pas après reboot du serveur | Vérifier que le service NSSM est configuré en démarrage automatique (Services.msc → QuestionnaireApp → Type de démarrage = Automatique). |
| Modifications du code non prises en compte | S'assurer d'avoir bien exécuté nssm stop / nssm start après la mise à jour du code (voir étape 13). |
Document préparé le 18 août 2026.