meta données pour cette page
  •  

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

certif:procedure:miseenplaceserveur:serveurdotnet [2026/08/18 14:12] – créée nicolascertif:procedure:miseenplaceserveur:serveurdotnet [2026/08/18 14:16] (Version actuelle) nicolas
Ligne 1: Ligne 1:
-====== Guide de déploiement — Application .NET (module Forms Stimulsoft) sur Windows Server + IIS ======+====== Guide de déploiement — API .NET (Stimulsoft.PDF.Forms + EF Core SQLite) sur Windows Server + IIS ======
  
-//Précision importante ce guide couvre le déploiement de **votre application .NET** qui intègre le module Forms de Stimulsoft (bibliothèque/NuGetex. Stimulsoft.Forms.Web ou équivalent) — pas l'installation du produit packagé « Stimulsoft Server ». Il s'agit donc d'un déploiement .NET classique, avec quelques points d'attention spécifiques à Stimulsoft (licence, taille des requêtesdétaillés à l'étape 6.//+//Projet réel ASP.NET Core Web API, .NET 8, packages Stimulsoft.PDF.Forms (génération de formulaires PDF côté serveur, en paire avec le package Angular ''stimulsoft-forms'côté client) et Microsoft.EntityFrameworkCore.Sqlite (base de données SQLite locale).//
  
-//Hypothèse retenue : application **ASP.NET Core** (.NET 6/7/8/9), le cas le plus courant pour un projet récent (les exemples officiels Stimulsoft pour Forms sont fournis en ASP.NET Core). Si votre application est en réalité en **.NET Framework classique** (4.x), prévenez-moi — la démarche est plus simple encore (pas de module à installer, IIS gère nativement le pipeline .NET Framework).// +//Topologie retenue : cette API est déployée sur un **site/domaine séparé** de l'application Angular (ex. ''api.mondomaine.local'' vs ''questionnaire.mondomaine.local''). Cela implique de configurer explicitement **CORS** pour que le frontend Angular soit autorisé à appeler l'API — voir étape 5.//
- +
-**Comment vérifier rapidement lequel s'applique à vous :** ouvrez le fichier ''.csproj'' du projetS'il contient une ligne ''<TargetFramework>net8.0</TargetFramework>'' (ou net6.0, net7.0, net9.0...), c'est de l'ASP.NET Core → ce guide s'appliqueS'il contient plutôt ''<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>'' (ancien format de fichier projet, souvent plus long et verbeux), c'est du .NET Framework classique → dites-le-moi, je vous ferai la version adaptée. +
- +
-Bonne nouvelle par rapport à Node.js ou Angular : IIS et .NET sont conçus par le même éditeur (Microsoft) pour fonctionner ensemble nativement. Il n'y a **pas besoin de NSSM, pas de reverse proxy à configurer manuellement, pas de port applicatif à gérer** — IIS héberge directement le process .NET via un module dédié (ASP.NET Core Module), et redémarre l'application automatiquement si elle plante. C'est le déploiement le plus simple des trois guides que je vous ai faits. +
- +
-> Le sommaire ci-dessous est généré automatiquement par DokuWiki à partir des titres de section.+
  
 ---- ----
Ligne 15: Ligne 9:
 ===== 1. Objectif et architecture ===== ===== 1. Objectif et architecture =====
  
-Ce document décrit comment déployer une application ASP.NET Core sur un Windows Server existanthébergée par IIS.+Ce guide décrit le déploiement d'une API ASP.NET Core (.NET 8) sur un Windows Server via IIS, en tant que backend séparé pour l'application Angular (déjà couverte dans un guide dédié). L'API génère des formulaires PDF via Stimulsoft.PDF.Forms et persiste ses données dans une base SQLite locale au serveur (fichier unique, pas de serveur de base de données séparé). 
 + 
 +Comme pour tout ASP.NET Core, IIS héberge l'application **in-process** via le module ASP.NET Core (ANCM) : pas de process séparé à surveiller, pas de reverse proxy manuel, IIS démarre/redémarre l'API automatiquement.
  
-Le modèle d'hébergement par défaut est dit **« in-process »** : l'application .NET Core tourne directement à l'intérieur du process de travail IIS (''w3wp.exe''), via un module natif appelé **ASP.NET Core Module (ANCM)**Contrairement à Node.js, il n'y a donc pas de process Node séparé à démarrer/surveiller (pas de NSSM), ni de reverse proxy à configurer à la main (pas de règle URL Rewrite vers un port local) — IIS gère tout nativement, y compris le démarrage automatique au boot et le redémarrage en cas de plantage.+**Schéma :** Angular (autre site/domaine) → appels HTTPS avec en-têtes CORS → IIS (port 443, certificat SSL→ module ANCM → API .NET (Stimulsoft.PDF.Forms + EF Core→ fichier SQLite local sur le serveur.
  
-**Schéma :** Internet → IIS (port 443, certificat SSL) → module ASP.NET Core (ANCM) → application .NET hébergée directement dans le worker process IIS.+**Point d'attention spécifique à ce projet, à garder en tête tout du long :** le fichier de base SQLite ne doit **jamais** se trouver dans le dossier qui sera écrasé à chaque déploiement (sous peine de perdre les données à la prochaine mise à jour) — voir étape 4.
  
 ===== 2. Prérequis ===== ===== 2. Prérequis =====
Ligne 25: Ligne 21:
   * Accès administrateur au Windows Server (2016, 2019, 2022 ou équivalent).   * Accès administrateur au Windows Server (2016, 2019, 2022 ou équivalent).
   * Le rôle « Serveur Web (IIS) » disponible via Gestionnaire de serveur.   * Le rôle « Serveur Web (IIS) » disponible via Gestionnaire de serveur.
-  * Le SDK .NET installé sur le poste/pipeline de build (pas nécessairement sur le serveur) pour publier l'application+  * Le SDK .NET installé sur le poste/pipeline de build. 
-  * Le code de l'application prêtavec un ''.csproj'' valide+  * Un nom de domaine ou sous-domaine dédié à l'API (distinct de celui de l'Angular)ex. ''api.mondomaine.local''
-  * Un nom de domaine ou sous-domaine interne pointant vers l'IP du serveur, si un accès via nom d'hôte est souhaité+  * Un certificat SSL pour ce domaine — indispensable ici en plus d'être une bonne pratique : la plupart des navigateurs bloquent les appels CORS depuis une origine HTTPS (l'Angular) vers une API en simple HTTP
-  * Un certificat SSL (interne ou public) si l'application doit être servie en HTTPS — fortement recommandé dès lors que le questionnaire collecte des données.+  * Le fichier de licence Stimulsoft (``license.key`` ou clé en dur selon votre implémentation).
  
 ===== 3. Étape 1 — Installer le rôle IIS ===== ===== 3. Étape 1 — Installer le rôle IIS =====
- 
-Si IIS n'est pas encore installé sur le serveur : 
  
 <code powershell> <code powershell>
Ligne 38: Ligne 32:
 Install-WindowsFeature -Name Web-Server -IncludeManagementTools Install-WindowsFeature -Name Web-Server -IncludeManagementTools
 </code> </code>
- 
-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. 
  
 ===== 4. Étape 2 — Installer le .NET Hosting Bundle ===== ===== 4. Étape 2 — Installer le .NET Hosting Bundle =====
  
-Étape **indispensable et spécifique à ASP.NET Core** : sans elle, IIS ne sait pas exécuter une application .NET Core (erreur 500.19 ou 502.5 sinon).+Indispensable pour qu'IIS sache exécuter une application .NET (sans elle, erreur 500.19 ou 502.5).
  
-  * Télécharger le « ASP.NET Core Runtime – Windows Hosting Bundle » correspondant à la version cible du projet (ex. .NET 8) depuis dotnet.microsoft.com/download/dotnet — bien prendre le **Hosting Bundle**, pas seulement le runtime standard : lui seul installe le module IIS ANCM+  * Télécharger le « ASP.NET Core Runtime 8.0 – Windows Hosting Bundle » depuis dotnet.microsoft.com/download/dotnet/8.0 (bien prendre le Hosting Bundle, pas le runtime seul)
-  * Lancer l'installeur (.exe) sur le serveur. +  * Lancer l'installeur sur le serveur. 
-  * Redémarrer IIS pour que le nouveau module soit pris en compte :+  * Redémarrer IIS :
  
 <code powershell> <code powershell>
Ligne 54: Ligne 46:
 </code> </code>
  
-  * Vérifier que le module est bien enregistré : dans IIS Manager, sélectionner le nœud du serveur → « Modules » → chercher ''AspNetCoreModuleV2'' dans la liste.+  * Vérifier dans IIS Manager → nœud serveur → « Modules » → présence de ''AspNetCoreModuleV2''.
  
-===== 5. Étape 3 — Publier l'application =====+===== 5. Étape 3 — Configurer CORS dans le code =====
  
-Sur le poste de build (ou directement sur le serveur si vous choisissez de builder sur place) :+Comme l'API et l'Angular sont sur deux origines différentes, le navigateur bloquera par défaut les appels de l'Angular vers l'API tant que CORS n'est pas explicitement autorisé côté serveur. Dans ''Program.cs''
 + 
 +<code csharp> 
 +var builder = WebApplication.CreateBuilder(args); 
 + 
 +builder.Services.AddCors(options => 
 +
 +    options.AddPolicy("AllowAngularApp", policy => 
 +    { 
 +        policy.WithOrigins("https://questionnaire.mondomaine.local") // origine exacte de l'Angular 
 +              .AllowAnyHeader() 
 +              .AllowAnyMethod(); 
 +        // .AllowCredentials() si l'API utilise des cookies d'authentification 
 +    }); 
 +}); 
 + 
 +// ... reste de la configuration ... 
 + 
 +var app = builder.Build(); 
 + 
 +app.UseCors("AllowAngularApp"); 
 + 
 +// ... app.MapControllers(); etc. 
 +</code> 
 + 
 +> **Remplacer l'URL par la vraie origine de production** de l'Angular (protocole + domaine + port exact). Une politique CORS trop permissive (``AllowAnyOrigin``) est déconseillée dès lors que l'API traite des données de questionnaire. 
 + 
 +===== 6. Étape 4 — Préparer un emplacement persistant pour la base SQLite ===== 
 + 
 +**C'est l'étape la plus importante à ne pas manquer sur ce projet.** Si la chaîne de connexion SQLite par défaut (souvent ''Data Source=app.db'' dans ''appsettings.json'') pointe vers un chemin relatif, le fichier se crée dans le dossier de l'application — c'est-à-dire exactement le dossier qui sera écrasé/synchronisé à chaque redéploiement. Résultat : toutes les réponses au questionnaire disparaissent au prochain déploiement. 
 + 
 +  * Créer un dossier dédié, en dehors de tout dossier de déploiement, ex. ''D:\Data\questionnaire-api\''
 +  * Dans ''appsettings.Production.json'' (créé s'il n'existe pas encore, à côté d'''appsettings.json'' dans le projet), définir un chemin absolu : 
 + 
 +<code json> 
 +
 +  "ConnectionStrings":
 +    "DefaultConnection": "Data Source=D:\\Data\\questionnaire-api\\app.db" 
 +  } 
 +
 +</code> 
 + 
 +  * S'assurer que le code lit bien cette clé de configuration (``builder.Configuration.GetConnectionString("DefaultConnection")``) plutôt qu'une valeur en dur. 
 +  * Donner au compte du pool d'application IIS (par défaut ''IIS AppPool\<NomDuPool>'') les droits de **lecture et écriture** sur ''D:\Data\questionnaire-api\'' (clic droit sur le dossier → Propriétés → Sécurité → Ajouter → saisir ''IIS AppPool\NomDuPool'' → Modifier)
 +  * Si des migrations EF Core doivent s'appliquer au démarrage (``dbContext.Database.Migrate()``), vérifier qu'elles s'exécutent bien contre ce chemin en production, et prévoir une sauvegarde du fichier ''app.db'' avant toute mise à jour du schéma. 
 + 
 +> **Sauvegardes :** un fichier SQLite se sauvegarde simplement en copiant le fichier ''.db'' (idéalement pool arrêté, ou via l'outil ''backup'' de SQLite pour une copie à chaud cohérente). Mettre en place une tâche planifiée de copie régulière de ''D:\Data\questionnaire-api\app.db'' vers un emplacement de sauvegarde. 
 + 
 +===== 7. Étape 5 — Publier l'application =====
  
 <code bash> <code bash>
Ligne 64: Ligne 104:
 </code> </code>
  
-Le dossier ''publish/'' généré contient les DLL de l'applicationses dépendances, et surtout un fichier **''web.config'' déjà généré automatiquement** par la commande publish — il contient la configuration nécessaire pour qu'IIS sache démarrer l'application via ANCM (chemin vers l'exécutable/DLL, modèle d'hébergement in-processetc.). Il n'y a normalement rien à modifier dedans pour un déploiement standard.+Le dossier ''publish/'' contient les DLL, les dépendances (dont les assemblies Stimulsoft.PDF.Forms), et un ''web.config'' généré automatiquement configurant le module ANCM. 
 + 
 +> Vérifier que ''appsettings.Production.json'' (étape 4) etle cas échéant, ''license.key'' (étape 8sont bien présents dans ce dossier publié — les fichiers de configuration/licence ne sont inclus que s'ils sont correctement référencés dans le ''.csproj'' (propriété « Copy to Output Directory »).
  
-===== 6. Étape — Copier les fichiers vers le serveur =====+===== 8. Étape — Copier les fichiers vers le serveur =====
  
-Copier l'intégralité du dossier ''publish/'' vers un dossier dédié sur le serveur, par exemple ''D:\Sites\questionnaire\''.+Copier le dossier ''publish/'' vers un dossier dédié, par exemple ''D:\Sites\questionnaire-api\'' — bien distinct du dossier de données créé à l'étape 4.
  
 <code bash> <code bash>
-# Exemple avec robocopy, en local sur le serveur ou via un partage réseau +robocopy publish D:\Sites\questionnaire-api /MIR
-robocopy publish D:\Sites\questionnaire /MIR+
 </code> </code>
  
-===== 7. Étape — Créer le site dans IIS Manager =====+> **Rappel :** ''/MIR'' supprime côté serveur tout ce qui n'est pas dans le dossier source. Comme la base SQLite est désormais hors de ce dossier (étape 4), elle ne sera jamais affectée par cette commande — c'est précisément l'objectif. 
 + 
 +===== 9. Étape — Créer le site dans IIS Manager =====
  
   - Ouvrir IIS Manager → clic droit sur « Sites » → Ajouter un site web.   - Ouvrir IIS Manager → clic droit sur « Sites » → Ajouter un site web.
-  - Nom du site : ex. QuestionnaireApp+  - Nom du site : ex. QuestionnaireAPI
-  - Chemin d'accès physique : D:\Sites\questionnaire\ (le dossier contenant le web.config généré par dotnet publish)+  - Chemin d'accès physique : D:\Sites\questionnaire-api\. 
-  - Liaison (Binding) : type http, port 80 (et https / port 443 une fois le certificat installé, voir étape suivante), nom d'hôte = le domaine/sous-domaine prévu+  - Liaison (Binding) : type https de préférence dès le départ (voir étape 10 pour le certificat), nom d'hôte = ''api.mondomaine.local''
-  - Pool d'applications : créer ou assigner un pool dédié, en mode **« No Managed Code »** — contrairement à une application .NET Framework classiqueASP.NET Core ne passe pas par le pipeline géré historique d'IIS, c'est le module ANCM qui gère tout. +  - Pool d'applications : dédié, en mode « No Managed Code ». 
-  - Démarrer le site.+  - Forcer explicitement l'environnement de productionpour être sûr qu'''appsettings.Production.json'' est bien utilisé et que les pages d'erreurs détaillées de développement sont désactivées — ajouter dans le web.config (dans la balise ''<aspNetCore>'') :
  
-**Identité du pool d'application :** vérifier que le compte utilisé par le pool (par défaut ''ApplicationPoolIdentity'') a les droits de lecture sur le dossier ''D:\Sites\questionnaire\'', et d'écriture sur le sous-dossier de logs si la journalisation stdout est activée (étape 10).+<code xml> 
 +<aspNetCore processPath="dotnet" arguments=".\QuestionnaireApi.dll" hostingModel="InProcess"> 
 +  <environmentVariables> 
 +    <environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Production" /> 
 +  </environmentVariables> 
 +</aspNetCore> 
 +</code>
  
-===== 8Étape 6 — Points spécifiques au module Forms Stimulsoft =====+  - Démarrer le site.
  
-==== 6.1 Déployer la clé de licence ====+===== 10Étape 8 — Licence Stimulsoft et taille des requêtes =====
  
-Stimulsoft charge sa licence soit par code (clé en dur dans le ''Program.cs''/contrôleur), soit par fichier (''license.key''). Si votre code utilise la seconde méthode — typiquement :+==== 10.1 Déployer la clé de licence ====
  
-<code csharp> +Si le code charge la licence par fichier (``Stimulsoft.Base.StiLicense.LoadFromFile(path)``), vérifier que ce fichier ''license.key'' est bien copié dans ''publish/'' puis présent sur le serveur au chemin attendu. Si elle est chargée par code (clé en dur dans ''Program.cs''), rien à déployer séparément, mais vérifier qu'elle n'est pas accidentellement liée à un environnement de développement uniquement (exclé d'essai).
-var path = Path.Combine(hostEnvironment.ContentRootPath, "Content\\license.key"); +
-Stimulsoft.Base.StiLicense.LoadFromFile(path)+
-</code> +
- +
-— assurez-vous que ce fichier ''license.key'' est bien copié dans le dossier ''publish/'' lors du ''dotnet publish'' (propriété « Copy to Output Directory » sur le fichier dans le projet), puis vérifiez sa présence une fois copié sur le serveurau même chemin relatif attendu par le code (ex. ''D:\Sites\questionnaire\Content\license.key''). Un oubli de ce fichier au déploiement est une cause fréquente d'erreur de licence en production alors que tout fonctionne en local.+
  
-==== 6.2 Taille maximale des requêtes ====+==== 10.2 Taille maximale des requêtes ====
  
-Les formulaires Stimulsoft peuvent transporter des données volumineuses (pièces jointes, images intégrées, export de rapports). Si vous rencontrez une erreur HTTP 404.13 ou 413 lors de la soumission d'un formulaire un peu chargé, augmentez la limite dans le web.config :+La génération/soumission de formulaires PDF peut impliquer des payloads plus volumineux que la moyenne (documents, images intégrées). Si erreur 404.13 ou 413 :
  
 <code xml> <code xml>
Ligne 108: Ligne 152:
     <requestFiltering>     <requestFiltering>
       <requestLimits maxAllowedContentLength="52428800" />       <requestLimits maxAllowedContentLength="52428800" />
-      <!-- 52428800 = 50 Mo, à ajuster selon vos besoins -->+      <!-- 50 Mo, à ajuster -->
     </requestFiltering>     </requestFiltering>
   </security>   </security>
Ligne 114: Ligne 158:
 </code> </code>
  
-Si l'application est en ASP.NET Core, vérifier également, côté code, la configuration Kestrel/formOptions correspondante (''MultipartBodyLengthLimit'', ''MaxRequestBodySize'') si elle est explicitement définie dans ''Program.cs''.+===== 11Étape 9 — Configurer HTTPS =====
  
-===== 9Étape 7 — Configurer HTTPS =====+  * Obtenir un certificat SSL pour ''api.mondomaine.local'' (interne ou public selon l'exposition). 
 +  * IIS Manager → site → « Certificats de serveur » → importer le certificat, puis ajouter une liaison https sur le port 443. 
 +  * Vérifier que ``app.UseHttpsRedirection()`` est bien présent dans ''Program.cs'' pour rediriger automatiquement le trafic HTTP restant vers HTTPS.
  
-Fortement recommandé dès que le questionnaire transmet des données, même peu sensibles. +===== 12. Étape 10 — Pare-feu Windows =====
- +
-  * Obtenir un certificat SSL : certificat interne (PKI de l'entreprise) si le site n'est accessible qu'en interne, ou certificat public (ex. Let's Encrypt, via l'outil win-acme, ou un certificat acheté) si le site est exposé sur Internet. +
-  * Dans IIS Manager, sélectionner le site → « Certificats de serveur » → importer le certificat. +
-  * Ajouter une liaison https sur le port 443 pour le site, en sélectionnant ce certificat. +
-  * Forcer la redirection HTTP → HTTPS : le plus simple ici est d'activer ''app.UseHttpsRedirection()'' directement dans le code (''Program.cs''), déjà présent par défaut dans la plupart des templates ASP.NET Core. Alternative sans toucher au code : utiliser le module URL Rewrite d'IIS avec une règle de redirection identique à celle des guides précédents. +
- +
-===== 10. Étape — Pare-feu Windows ===== +
- +
-Autoriser uniquement les ports nécessaires en entrée : 80 et 443. Il n'y a ici aucun port applicatif interne à ouvrir (le module ANCM communique avec l'application via un canal interne, pas un port TCP exposé).+
  
 <code powershell> <code powershell>
-New-NetFirewallRule -DisplayName "IIS HTTP" -Direction Inbound -Protocol TCP -LocalPort 80 -Action Allow +New-NetFirewallRule -DisplayName "IIS HTTPS API" -Direction Inbound -Protocol TCP -LocalPort 443 -Action Allow 
-New-NetFirewallRule -DisplayName "IIS HTTPS" -Direction Inbound -Protocol TCP -LocalPort 443 -Action Allow+New-NetFirewallRule -DisplayName "IIS HTTP API" -Direction Inbound -Protocol TCP -LocalPort 80 -Action Allow
 </code> </code>
  
-===== 11. Étape — Tester le déploiement =====+===== 13. Étape 11 — Tester le déploiement =====
  
-  - Depuis un poste client accéder à ''http://nom-du-site'' puis ''https://nom-du-site'' dans un navigateur : l'application doit répondre+  - Depuis un poste : ''https://api.mondomaine.local/swagger'' (si Swagger est activé pour un test ponctuel) ou un endpoint connu de l'API doit répondre. 
-  - Vérifier que le questionnaire fonctionne de bout en bout (soumissionenregistrement des réponses)+  - Depuis l'application Angular réelle (pas juste Postman) vérifier qu'un appel vers l'API ne remonte pas d'erreur CORS dans la console navigateur (message typique « has been blocked by CORS policy »). Si c'est le cas, revérifier l'origine exacte configurée à l'étape 5 (protocole, casse du domaine, port)
-  - Provoquer volontairement un arrêt du pool d'application (Arrêter puis Démarrer dans IIS Manager) et vérifier que le site répond de nouveau normalement après redémarrage — IIS/ANCM relance automatiquement l'application à la requête suivante+  - Générer un formulaire PDF de test de bout en bout, en conditions réelles depuis l'Angular
-  - Redémarrer le serveur et vérifier que le site est de nouveau accessible sans intervention manuelle (IIS démarre automatiquement au boot).+  - Vérifier que la base SQLite se remplit bien au bon endroit (''D:\Data\questionnaire-api\app.db'' grossit après une soumission)
 +  - Redémarrer le serveur et vérifier la reprise automatique du site.
  
-===== 12. Étape 10 — Activer les logs (diagnostic=====+===== 14. Étape 12 — Logs et diagnostic =====
  
-Par défaut, les logs détaillés de l'application (stdout) ne sont pas activés — utile de les activer temporairement en cas de problème. Dans le ''web.config'' généré par ''dotnet publish'', repérer la balise ''aspNetCore'' et ajuster :+Activer temporairement les logs stdout dans le web.config en cas de problème :
  
 <code xml> <code xml>
-<aspNetCore processPath="dotnet" +<aspNetCore processPath="dotnet" arguments=".\QuestionnaireApi.dll" 
-            arguments=".\QuestionnaireApp.dll" +            stdoutLogEnabled="true" stdoutLogFile=".\logs\stdout"
-            stdoutLogEnabled="true" +
-            stdoutLogFile=".\logs\stdout"+
             hostingModel="InProcess" />             hostingModel="InProcess" />
 </code> </code>
  
-Créer le sous-dossier ''logs\'' à côté du web.config (IIS ne le crée pas automatiquement) et s'assurer que le pool d'application a le droit d'y écrireUne fois le diagnostic terminé, repasser ''stdoutLogEnabled'' à ''false'' pour éviter une accumulation de fichiers. +Créer le sous-dossier ''logs\'' avec droits d'écriture pour le pool d'application. Consulter aussi l'Observateur d'événements Windows (Journaux Windows → Application) pour les erreurs de démarrage du module ANCMRepasser ''stdoutLogEnabled'' à ''false'' une fois le diagnostic terminé.
- +
-Les logs IIS classiques restent aussi disponibles dans ''%SystemDrive%\inetpub\logs\LogFiles\'', et les erreurs de démarrage du module ANCM apparaissent dans l'Observateur d'événements Windows (Journaux Windows → Application). +
- +
-===== 13Étape 11 — Sécuriser l'application =====+
  
-  * Activer HSTS (''app.UseHsts()'', déjà présent par défaut dans la plupart des templates hors environnement de développement). +===== 15Étape 13 — Sécuriser l'API =====
-  * Valider et assainir les entrées du questionnaire côté serveur (pas seulement côté client). +
-  * Ne jamais stocker de secrets (chaînes de connexion, clés API) en clair dans ''appsettings.json'' déployé — utiliser des variables d'environnement, le gestionnaire de secrets IIS, ou un coffre-fort (ex. Azure Key Vault si applicable). +
-  * Restreindre les droits NTFS du dossier ''D:\Sites\questionnaire\'' pour que seuls les comptes de déploiement/administration puissent y écrire. +
-  * Mettre en place une limite de débit si nécessaire (middleware ''Microsoft.AspNetCore.RateLimiting'', inclus nativement depuis .NET 7).+
  
-===== 14. Étape 12 — Procédure de mise à jour de l'application =====+  * Confirmer que Swagger/OpenAPI (s'il est présent dans le projet) est bien désactivé ou protégé en production — ne pas l'exposer publiquement sans authentification. 
 +  * Restreindre la politique CORS à l'origine exacte de l'Angular (étape 5), jamais ``AllowAnyOrigin`` en production. 
 +  * Restreindre les droits NTFS de ''D:\Sites\questionnaire-api\'' et ''D:\Data\questionnaire-api\'' aux seuls comptes nécessaires (déploiement, pool d'application). 
 +  * Ne jamais committer ''appsettings.Production.json'' ou ''license.key'' dans un dépôt Git public — les gérer comme des secrets de déploiement. 
 +  * Valider côté serveur toutes les entrées reçues de l'Angular, même si elles sont déjà validées côté client.
  
-  - Sur le poste de build : récupérer la nouvelle version du code, puis relancer ''dotnet publish -c Release -o ./publish''+===== 16Étape 14 — Procédure de mise à jour de l'application =====
-  - Avant de copier les nouveaux fichiers, déposer un fichier ''app_offline.htm'' à la racine de ''D:\Sites\questionnaire\'' : IIS/ANCM détecte sa présence et arrête proprement l'application, libérant les DLL verrouillées (sans ça, la copie peut échouer si les fichiers sont en cours d'utilisation). +
-  - Copier les nouveaux fichiers (''robocopy publish D:\Sites\questionnaire /MIR'', en excluant ''app_offline.htm'' s'il est encore présent côté serveur). +
-  - Supprimer ''app_offline.htm'' : l'application redémarre automatiquement à la requête suivante. +
-  - Vérifier rapidement (étape 9) que le site répond correctement.+
  
-> **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 du dossier ''publish/'' pour pouvoir revenir en arrière rapidement en cas de problème.+  - Sur le poste de build ''dotnet publish -c Release -o ./publish''
 +  - Optionnel mais recommandé avant une mise à jour de schéma : copier ''D:\Data\questionnaire-api\app.db'' vers un emplacement de sauvegarde. 
 +  - Déposer un ''app_offline.htm'' à la racine de ''D:\Sites\questionnaire-api\'' pour libérer proprement les fichiers verrouillés. 
 +  - ''robocopy publish D:\Sites\questionnaire-api /MIR'' (la base de données, hors de ce dossier, n'est pas affectée). 
 +  - Supprimer ''app_offline.htm''
 +  - Vérifier (étape 11) que l'API répond correctement et que les données existantes sont toujours présentes.
  
-===== 15. Checklist finale =====+===== 17. Checklist finale =====
  
 ^ Élément ^ Statut ^ ^ Élément ^ Statut ^
 | Rôle IIS installé | ☐ | | Rôle IIS installé | ☐ |
-| .NET Hosting Bundle installé, module AspNetCoreModuleV2 vérifié | ☐ |+| .NET Hosting Bundle installé, AspNetCoreModuleV2 vérifié | ☐ | 
 +| Politique CORS configurée avec l'origine exacte de l'Angular | ☐ | 
 +| Dossier de données SQLite créé hors du dossier de déploiement | ☐ | 
 +| Chaîne de connexion pointant vers ce dossier (appsettings.Production.json) | ☐ | 
 +| Droits NTFS du pool d'application sur le dossier de données | ☐ |
 | Application publiée (dotnet publish -c Release) | ☐ | | Application publiée (dotnet publish -c Release) | ☐ |
-| Fichiers copiés sur le serveur (dossier publish/, avec web.config) | ☐ | +| Fichiers copiés sur le serveur (web.config inclus) | ☐ | 
-Site créé dans IIS, pool en « No Managed Code » | ☐ | +| license.key présent sur le serveur si utilisé | ☐ | 
-| Fichier license.key présent sur le serveur, au bon chemin | ☐ | +| Limite de taille des requêtes ajustée si besoin | ☐ | 
-| Limite de taille des requêtes (maxAllowedContentLength) ajustée si besoin | ☐ | +Site créé dans IIS, pool en « No Managed Code », ASPNETCORE_ENVIRONMENT=Production | ☐ |
-Binding http configuré | ☐ |+
 | Certificat SSL installé, binding https configuré | ☐ | | Certificat SSL installé, binding https configuré | ☐ |
-| Redirection HTTP → HTTPS active | ☐ | 
 | Pare-feu : ports 80/443 ouverts | ☐ | | Pare-feu : ports 80/443 ouverts | ☐ |
-Test de bout en bout du questionnaire réussi | ☐ | +Appel depuis l'Angular réel sans erreur CORS | ☐ | 
-Redémarrage serveur testé (reprise automatique) | ☐ | +| Génération de PDF testée de bout en bout | ☐ | 
-Droits NTFS restreints sur le dossier du site | ☐ | +Base SQLite vérifiée au bon emplacement, hors dossier de déploiement | ☐ | 
-Secrets non stockés en clair (appsettings) | ☐ |+Sauvegarde de la base SQLite planifiée | ☐ | 
 +Swagger désactivé/protégé en production | ☐ |
  
-===== 16. Annexe — Dépannage rapide =====+===== 18. Annexe — Dépannage rapide =====
  
 ^ Symptôme ^ Piste de résolution ^ ^ Symptôme ^ Piste de résolution ^
-| Erreur HTTP 500.19 | web.config invalideou module ANCM absent — vérifier que le Hosting Bundle est bien installé (pas seulement le runtime standard). | +| Erreur CORS dans la console navigateur | Vérifier l'origine exacte déclarée dans WithOrigins (protocole, domaine, port), et que app.UseCors(...) est bien appelé avant app.MapControllers(). | 
-| Erreur HTTP 500.30 (in-process start failure) | L'application plante au démarrage — activer stdoutLogEnabled (étape 9) et consulter l'Observateur d'événements Windows pour l'exception exacte. | +| Les données disparaissent après un déploiement | La base SQLite était encore dans le dossier de déploiement écrasé par /MIR — la déplacer vers un dossier persistant (étape 4) et restaurer depuis une sauvegarde si disponible. | 
-| Erreur HTTP 500.31 / 502.5 | Le module ANCM ne trouve pas l'application ou une version du runtime incompatible — vérifier la version du Hosting Bundle installée vs le TargetFramework du projet. | +| Erreur d'accès refusé sur le fichier .db | Droits NTFS insuffisants pour le compte IIS AppPool\<NomDuPool> sur le dossier de données. | 
-| Le site ne répond pas après une mise à jour | Vérifier qu'''app_offline.htm'' a bien été retiré après la copie des nouveaux fichiers. | +| Erreur HTTP 500.19 | web.config invalide ou Hosting Bundle absent. | 
-| Erreur d'accès refusé lors du démarrage | Droits NTFS insuffisants pour le compte du pool d'application (''ApplicationPoolIdentity''sur le dossier du site ou le sous-dossier logs. | +| Erreur HTTP 500.30 (in-process start failure) | Activer stdoutLogEnabled et consulter l'Observateur d'événements Windows pour l'exception exacte (souvent une erreur de connexion à la base ou de licence Stimulsoft au démarrage). | 
-| 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é. | +| Erreur de licence Stimulsoft en production | license.key absent du dossier publié, ou chemin de chargement incorrect (voir étape 8.1). | 
-| Erreur de licence Stimulsoft en production (fonctionne en local) Le fichier license.key n'a probablement pas été copié dans le dossier publié — vérifier sa présence sur le serveur au chemin exact attendu par le code (étape 6.1). | +| Erreur 404.13 413 sur soumission de formulaire | Augmenter maxAllowedContentLength (étape 8.2). |
-| Erreur 404.13 ou 413 lors de la soumission d'un formulaire volumineux Limite de taille de requête IIS trop basse — augmenter maxAllowedContentLength dans le web.config (étape 6.2). |+
  
 ---- ----
  
 //Document préparé le 18 août 2026.// //Document préparé le 18 août 2026.//