Comment s'assurer que nous publions la production sur le serveur de production et testons sur le serveur de test
-
19-08-2019 - |
Question
J'ai une entrée dans mon fichier Web.Config qui indique l'environnement dans lequel je me trouve pour les chaînes de connexion et les fichiers indésirables:
<add key="AppEnv" value ="2" /> <!--(0 = Dev, 1 = test, 2 = prod)-->
Je cherche un moyen d'alerter le développeur, au moment de la publication, pour qu'il vérifie cette clé / valeur afin qu'il ne publie pas le 'test' sur le serveur 'prod' et vice versa. .
Merci
La solution
J'ai mis au point ma propre solution (probablement non conventionnelle) à ce problème. Nous avons développé de nombreux projets Web différents pour de nombreux clients différents et les avons tous migrés vers cette méthode en raison de tous les problèmes que nous avons rencontrés avec plusieurs fichiers web.config ou des éditions requises avant la publication.
En gros, nous laissons notre application nous indiquer dans quel environnement elle s'exécute en fonction de l'URL entrante. Nous initialisons ceci à la première demande et le stockons en mémoire pour la durée de vie de l'application. De cette façon, nous pouvons stocker chacune des valeurs de configuration spécifiques à notre environnement dans le même fichier de configuration et les qualifier simplement avec Développement, Staging, Production, etc. Et tous les paramètres qui ne diffèrent pas d'un environnement à l'autre ne doivent pas nécessairement être qualifiés.
D'abord un exemple de fichier web.config:
<appSettings>
<add key="DevelopmentHost" value="dev.trackmyhours.com" />
<add key="StagingHost" value="staging.trackmyhours.com" />
<add key="ProductionHost" value="www.trackmyhours.com" />
</appSettings>
<connectionStrings>
<clear />
<add name="DevelopmentConnectionString" connectionString="your dev conn string" providerName="System.Data.SqlClient" />
<add name="StagingConnectionString" connectionString="your staging conn string (mine is typically same as staging)" providerName="System.Data.SqlClient" />
<add name="ProductionConnectionString" connectionString="your production conn string" providerName="System.Data.SqlClient" />
</connectionStrings>
Ensuite, nous avons un "App" " classe qui nous donne accès à notre " Site " classe, mais vous pouvez concevoir vos classes comme bon vous semble.
Public Class App
Private Shared _Site As New Site
Public Shared ReadOnly Property Site() As Site
Get
Return _Site
End Get
End Property
End Class
Imports System.Configuration
Imports System.Web
Public Class Site
Public Enum EnvironmentType
Development
Staging
Production
End Enum
Friend Sub New()
If HttpContext.Current IsNot Nothing Then
Dim URL = HttpContext.Current.Request.Url.DnsSafeHost
Select Case URL
Case ConfigurationManager.AppSettings("DevelopmentHost"), "localhost"
_Environment = EnvironmentType.Development
Case ConfigurationManager.AppSettings("StagingHost")
_Environment = EnvironmentType.Staging
Case ConfigurationManager.AppSettings("ProductionHost")
_Environment = EnvironmentType.Production
End Select
Else
'probably getting called from a winforms/console app, or unit tests
_Environment = EnvironmentType.Staging
End If
_ConnectionString = ConfigurationManager.ConnectionStrings(_Environment.ToString & "ConnectionString").ConnectionString
End Sub
Private _Environment As EnvironmentType
Public Property Environment() As EnvironmentType
Get
Return _Environment
End Get
Set(ByVal value As EnvironmentType)
_Environment = value
_ConnectionString = ConfigurationManager.ConnectionStrings(_Environment.ToString & "ConnectionString").ConnectionString
End Set
End Property
Private _ConnectionString As String
Public ReadOnly Property ConnectionString() As String
Get
Return _ConnectionString
End Get
End Property
End Class
Nous avons placé nos classes dans notre bibliothèque de classes Biz Object. Nous avons juste décidé qu'il n'était pas nécessaire de déterminer l'environnement pour chaque requête, car il ne pouvait vraiment pas changer pendant la durée de vie de l'application. En outre, cela nous permet de référencer App.Site.Environment à partir de ANWHERE dans le code de la bibliothèque ou dans le code situé derrière. Ceci est également utile si vous devez ajouter une logique conditionnelle dans votre code, comme par exemple ne pas envoyer de courriels à de vraies personnes lors de l'exécution de dev / staging.
Une dernière chose - pour nos Linq2SQL ou EF Data / ObjectContexts, nous ne stockons pas la chaîne de connexion dans le fichier et surchargons le constructeur afin de pouvoir fournir notre chaîne de connexion d'environnement correcte, comme ceci:
Partial Class SampleDataContext
Sub New()
MyBase.New(App.Site.ConnectionString)
End Sub
End Class
Autres conseils
Voici une solution: stockez ce fichier sous le nom " Web.Config.in
" sous contrôle de source.
Sur chaque serveur (dev, test, stockage intermédiaire, production), copiez Web.Config.in
dans Web.Config
et modifiez le AppEnv valeur soigneusement.
À chaque passage ultérieur d'un environnement à l'autre, excluez les fichiers Web.Config
. C'est-à-dire, ne pas écraser ce fichier particulier. Écrire des scripts de déploiement qui exécutent rsync --exclude WebConfig
par exemple.
J'ai en caractères gras et en rouge sur le haut de la page le mode dans lequel se trouve le site s'il n'est pas en mode Production.
J'ai également une page de diagnostic qui répertorie le serveur en cours d'exécution et la base de données à laquelle il est connecté.
Vous pouvez également mettre une table de recherche dans chaque base de données, afin de vous assurer que le bon indicateur est connecté. (dans la base de test, marquez-le comme 1 et vérifiez sur Application_Start que les valeurs correspondent)
Chaque fois qu’un processus nécessite toujours plus d’une étape, je sais que je vais tout gâcher au moins la moitié du temps. Pour cette raison, j'aime MSBuild.
MSBuild contient un grand nombre de tâches utiles, telles que tâche AspNetCompiler , qui semble être une action de compilation / publication en une étape.
Plusieurs projets regroupent également un grand nombre de "services personnalisés". Tâches MSBuild à des fins diverses. Le projet Tâches de la communauté MSBuild comprend une tâche XmlMassUpdate utile pour apporter plusieurs modifications à un fichier au format xml. En d’autres termes, idéal pour mettre à jour les fichiers web.config.
J'ai trouvé un exemple d'utilisation de la tâche XmlMassUpdate avec un projet de déploiement Web ici .
Une question éternelle qui ne cesse de surgir! Je suppose que n'importe quel développeur ASP.NET sérieux s'est cogné la tête contre cela à certains égards.
Pour ASP.NET 4.0, de l'aide est fournie - les options de déploiement Web améliorées offrent une fonctionnalité appelée "transformations web.config".
Découvrez ceci Vidéo de la chaîne 9 sur le sujet - vous n'avez pas encore trouvé de référence écrite satisfaisante ...
Marc
Je prends toutes les clés qui seront différentes en test et en production et les place dans un fichier .config entièrement nouveau. Je mets les paramètres de test en test et les paramètres de production en production et ne copie jamais ce fichier de test en production. Ensuite, dans votre web.config habituel, vous pouvez spécifier ce nouveau fichier .config comme suit:
<appSettings file="ExternalWeb.config>
.... common keys go here
</appSettings>
sur le serveur de test, " external.config " contiendra les valeurs spécifiques à ce serveur et en production, il aura les valeurs prod. Cela vous permet de copier l'intégralité de votre web.config entre les 2 serveurs sans jamais modifier manuellement le fichier.
Je pense que c'est une mauvaise pratique de stocker les chaînes de connexion dans web.config. Je crée plutôt un fichier de configuration séparé en dehors de mes sites Web, à un emplacement connu tel que
.C: \ xxxx \ config.xml
Ensuite, je stocke tous les paramètres liés à la machine. Donc, sur mon serveur live, j'ai mes paramètres live, sur la chaîne de connexion du serveur de test vers la base de test et sur ma machine de développement, j'ai mes paramètres locaux. Ces paramètres peuvent également être consultés sur tous les sites Web et applications .net sur ce serveur. Mettre à jour uniquement un seul endroit lorsque la base de données change.
Parfait!
Définissez votre Web.Config sur "Lecture seule", il ne sera donc pas écrasé lors de la publication sur ces serveurs.
En contrepartie, vous devrez gérer manuellement vos web.configs sur chaque serveur. Votre publication sera considérée comme un échec car elle ne pourrait pas écraser le script web.config sur le serveur distant. mais à mon humble avis cela est préférable à la modification de la configuration chaque fois que vous effectuez un téléchargement