Как убедиться, что мы публикуем продукцию на рабочем сервере и тестируем на тестовом сервере

У меня есть запись в моем файле Web.Config, которая указывает, в какой среде я нахожусь для строк подключения и мусора:

<add key="AppEnv" value ="2" /> <!--(0 = Dev, 1 = test, 2 = prod)--> 

Я ищу способ предупредить разработчика во время публикации, чтобы убедиться, что он проверил этот ключ/значение, чтобы они не публиковали «тест» на «производственный» сервер и наоборот.

Спасибо


person Chris Burgess    schedule 16.03.2009    source источник


Ответы (8)


Я придумал свое (возможно, нестандартное) решение этой проблемы. Мы разрабатываем много разных веб-проектов для разных клиентов и перевели все их на этот метод из-за всех проблем, которые у нас были с несколькими файлами web.config, или из-за необходимости редактирования перед публикацией.

По сути, мы позволяем нашему приложению сообщать нам, в какой среде оно работает, на основе входящего URL-адреса. Мы инициализируем его при первом запросе и сохраняем в памяти на время жизни приложения. Таким образом, мы можем хранить каждое из значений конфигурации, специфичных для нашей среды, в одном и том же файле конфигурации и просто квалифицировать их с помощью Development, Staging, Production и т. д. И любые параметры, которые не различаются между средами, не нужно квалифицировать.

Сначала пример 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>

Затем у нас есть класс «Приложение», который дает нам доступ к нашему классу «Сайт», но вы можете спроектировать свои классы так, как считаете нужным.

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

Мы помещаем наши классы в нашу библиотеку классов Biz Object. Мы просто решили, что нет необходимости определять среду для каждого отдельного запроса, так как она действительно не может измениться в течение жизни приложения. Кроме того, это позволяет нам ссылаться на App.Site.Environment ОТ ЛЮБОГО МЕСТА в коде в библиотеке или коде позади. Это также полезно, если вам нужно добавить в свой код некоторую условную логику — например, не отправлять электронные письма реальным людям при работе в dev/staging.

И последнее: для наших Linq2SQL или EF Data/ObjectContexts мы не храним строку подключения в файле, а вместо этого перегружаем конструктор, чтобы мы могли указать правильную строку подключения к среде, например:

Partial Class SampleDataContext
    Sub New()
        MyBase.New(App.Site.ConnectionString)
    End Sub
End Class
person Kevin Lewis    schedule 21.05.2009

Вот решение: сохраните этот файл как «Web.Config.in» в системе управления версиями.

На каждом сервере (dev, test, staging, production) скопируйте Web.Config.in в Web.Config и тщательно отредактируйте значение AppEnv.

При каждом последующем переходе из одной среды в другую исключайте Web.Config файлов. То есть не перезаписывайте этот конкретный файл. Напишите сценарии развертывания, которые запускают, например, rsync --exclude WebConfig.

person Bill Karwin    schedule 16.03.2009

У меня вверху страницы жирным красным шрифтом написано, в каком режиме находится сайт, если он не в рабочем режиме.

У меня также есть страница диагностики, на которой указано, на каком сервере работает и к какой базе данных он подключен.

Вы также можете поместить таблицу поиска в каждую базу данных, чтобы убедиться, что к ней подключен правильный флаг. (в тестовой БД отметьте его как 1 и проверьте Application_Start на совпадение значений)

person Glennular    schedule 16.03.2009

Всякий раз, когда есть процесс, который всегда требует более одного шага, я знаю, что испорчу его по крайней мере в половине случаев. По этой причине я люблю MSBuild.

В комплекте с MSBuild поставляется довольно много полезных задач, таких как задача AspNetCompiler, которая представляет собой одноэтапное действие компиляции/публикации.

Также есть несколько проектов, объединяющих большое количество «настраиваемых» задач MSBuild для различных целей. В Проекте задач сообщества MSBuild есть задача XmlMassUpdate, которая полезна для внесения нескольких изменений в файл в формате xml. Другими словами, идеально подходит для обновления файлов web.config.

Я нашел пример использования задачи XmlMassUpdate совместно с проектом Web Deployment здесь.

person Daniel Pratt    schedule 16.03.2009

Вечный вопрос, который постоянно всплывает! Я полагаю, что почти любой серьезный разработчик ASP.NET так или иначе сталкивался с этим.

Для ASP.NET 4.0 есть некоторая помощь — улучшенные параметры веб-развертывания будут предлагать функцию, называемую «преобразования web.config».

Посмотрите этот Канал 9 видео по теме - пока не нашел достойной письменной ссылки...

Марк

person marc_s    schedule 17.03.2009

Я беру любые ключи, которые будут отличаться при тестировании и производстве, и помещаю их в совершенно новый файл .config. Я ставлю тестовые настройки на тест, а рабочие настройки на продакшен и никогда не копирую этот файл из теста в продакшен. Затем в обычном файле web.config вы можете указать этот новый файл .config следующим образом:

<appSettings file="ExternalWeb.config>
    .... common keys go here
</appSettings>

на тестовом сервере «external.config» будет содержать значения, характерные для этого сервера, а в рабочей среде он будет иметь значения prod. Это позволяет вам копировать весь файл web.config между двумя серверами, даже не изменяя файл вручную.

person iZ.    schedule 17.03.2009

Я считаю плохой практикой хранить строки подключения в web.config, вместо этого я создаю отдельный файл конфигурации за пределами моих веб-сайтов в общеизвестном месте, например

C:\xxxx\config.xml

Затем я сохраняю там все настройки, зависящие от машины. Так что на моем рабочем сервере у меня есть мои живые настройки, на тестовом сервере строки подключения к тестовой БД, а на моей машине Dev я получил свои локальные настройки. Затем эти настройки можно также повторить для всех веб-сайтов и приложений .net на этом сервере. Только одно место для обновления при изменении БД.

Идеальный!

person Community    schedule 09.05.2009

Установите для вашего Web.Config значение «Только для чтения», поэтому он не будет перезаписан при публикации на этих серверах.

Компромисс заключается в том, что вам придется вручную поддерживать свои файлы web.config на каждом сервере, и ваша публикация будет утверждать, что она не удалась, поскольку она не может перезаписать файл web.config на удаленном сервере; но ИМХО это предпочтительнее, чем изменять конфигурацию каждый раз, когда вы делаете загрузку

person Community    schedule 29.05.2009